标题:
STM8L的智能手持血糖监测设备的数据存储实现源码
[打印本页]
作者:
pxb2019
时间:
2019-2-20 10:16
标题:
STM8L的智能手持血糖监测设备的数据存储实现源码
为了克服红外无创血糖检测中 存在的难题, 使微弱的光谱信号变化能正确的体现人体血糖浓度, 作者根据朗伯—比尔定律原理, 分析 了人体葡萄糖的吸收谱, 设计了多波长红外血糖检测传感器阵列, 采用MOE 和MADALINE 整合神经网 络方法建立了传感器阵列信号处理模型, 使红外无创血糖检测的精度和稳定性得到了改善
单片机源程序如下:
#include "stm8l15x.h"
#include "./Protocol/Protocol.h"
#include "./LCD/Lcd_Driver.h"
#include "./RTC_CLK/RTC_CLK.h"
#include "./InPut/InPut_Driver.h"
#include "./IIC/I2C_Driver.h"
#include "./Flash/Flash_Driver.h"
#include "./UsrData/UsrData.h"
#include "stdio.h"
#include "main.h"
/*
*****************************************************************/
System_sContrl SystemCtr;
Main_sMenu MainMenu;
PassWdBrand_sContrl PassWordBrand;
/*
*****************************************************************/
/* 测试程序 */
void System_Delay(uint8_t nCount);
void Read_RTCTimes();
uint8_t System_AutoCheck();
uint8_t Time_Setting(void);
void ReadPasswdBrand();
uint8_t ReadPassWDMode();
uint8_t Recode_Header(uint32_t paddr,uint8_t *uData);
uint8_t Read_RecodeData(uint32_t paddr,uint8_t *uData);
uint8_t Verity_PassWord();
static void TIM4_Config(void);
static void USART_Config(void);
static void LCD_RTCConfig(void);
static void System_MainMenu();
void System_EventProcess();
void SystemDeviceInit();
void Halt_OffDevice();
void TestBoolMode();
void main(void)
{
CLK_SYSCLKDivConfig(CLK_SYSCLKDiv_1);
while(1)
{
/* 判断是否有输入 */
if(InputDevice.uType == NO_INPUT_DEV )
{
/* 判断系统是否激活状态 */
if( SystemCtr.uStatus != SYSTEM_ACTIVE )
{
/*进入halt模式关闭,外设
******************************************/
Halt_OffDevice();
/*****************************************/
halt(); //进入休眠模式
/*初始化系统外设init()
****************************************/
SystemDeviceInit();
/****************************************/
}
}
InPut_Process();
/* 系统处理过程
****************************************/
if(SystemCtr.uStatus == SYSTEM_ACTIVE)
{
System_MainMenu();
System_EventProcess();
Protocol_Process();
}
/****************************************/
}
}
/***************************************************************
* 函数名:System_MainMenu()
* 输入 :void
* 输出 :void
* 功能 :系统处理菜单
****************************************************************/
static void System_MainMenu()
{
if(SystemCtr.uStatus != SYSTEM_SLEEP)
{
if( ButtonClick.SystemVoiceKey == SET)
{
Display_Speeker(ENABLE);
}
else
{
Display_Speeker(DISABLE);
}
switch(MainMenu.uMenu)
{
case TESTING_BOOL_MENU:
{
Write_RecodeTest();
TestBoolMode();
}break;
case PASSWORD_BRAND_MENU:
{
if(ReadPassWDMode())
DisplayOutSlaverEro();
}break;
case SETTING_TIME_MENU:
{
Set_Calendar();
}break;
case RECODE_BLEMPTY_MENU:
{
DisplayNoneEmptyBool();
//Read_Recode();
}break;
case RECODE_BLNOEMPTY_MENU:
{
DisplayNoneUnEmptyBool();
}break;
case RECODE_BLINDENTY_MENU:
{
DisplayNoneIndentBool();
}break;
case ALARM_CLOCK_MENU:
{
Display_Alarm(ENABLE);
RTC_ITConfig(RTC_IT_ALRA, ENABLE);
RTC_AlarmCmd(ENABLE);
}break;
default :
{
SystemCtr.uStatus = SYSTEM_SLEEP;
}break;
}
}
}
/***************************************************************
* 函数名:Halt_OffDevice
* 输入 :void
* 输出 :void
* 功能 :进入halt模式前关闭外设
****************************************************************/
void Halt_OffDevice()
{
/* 关闭设备前,设置系统主时钟,和中断 */
CLK_SYSCLKDivConfig(CLK_SYSCLKDiv_1);
InPut_Init();
enableInterrupts();
LCD_ClearScreen();
CalendarSetting_Quit();
LCD_Cmd(DISABLE); //关闭LCD
}
/***************************************************************
* 函数名:SystemDeviceInit
* 输入 :void
* 输出 :void
* 功能 :初始化外设
****************************************************************/
void SystemDeviceInit()
{
CLK_SYSCLKSourceSwitchCmd(ENABLE);
/* System Clock is HSI/1 */
CLK_SYSCLKDivConfig(CLK_SYSCLKDiv_1);
/*初始化I2C端口*/
I2C_Init();
TIM4_Config();
USART_Config();
LCD_RTCConfig();
LCD_Init();
Protocol_Init();
}
/*******************************************************************
* 函数名:ReadPasswdBrand
* 输 入:void8
* 输 出:void
* 功 能:读密码牌操作
********************************************************************/
void ReadPasswdBrand()
{
while(Verity_PassWord())//如果校验码与插入读出的校验码不同回写
{
FLASH_SetProgrammingTime( FLASH_ProgramTime_Standard); //设置Flash操作
FLASH_unLock(MCU_EEPROM_DATA); //解锁数据存储区
while (!(FLASH->IAPSR & (uint8_t)0x08)); //等待解锁操作
/* 读取密码牌内容,数据搬移临界区 */
System_Delay(200);
IIC_SlaveRead_LongBuffer(PassWordBrand.DataBuffer,sizeof(PassWordBrand.DataBuffer));//读出密码牌数据
System_Delay(10);
FLASH_WriteLongBuffer(MCU_EEPROM_DATA,PassWordBrand.DataBuffer,sizeof(PassWordBrand.DataBuffer));
System_Delay(200);
/* ********************************************* */
while (FLASH_GetFlagStatus( FLASH_FLAG_EOP) == SET);
/* 读取内容测试
FLASH_ReadLongBuffer(MCU_EEPROM_DATA,ReadBuffer,sizeof(ReadBuffer));
while (FLASH_GetFlagStatus( FLASH_FLAG_EOP) == SET);*/
}
}
/*******************************************************************
* 函数名:ReadPassWDMode
* 输 入:void
* 输 出:void
* 功 能:读密码牌操作
********************************************************************/
uint8_t Verity_PassWord()
{
uint8_t uPassWord = 0;
uint8_t uFlash = 0;
if(PassWordBrand.uStatus != VERIFY_SUCESS)
{
LCD_Cmd(DISABLE); //关闭LCD
FLASH_SetProgrammingTime( FLASH_ProgramTime_Standard); //设置Flash操作
FLASH_unLock(MCU_EEPROM_DATA); //解锁数据存储区
while (!(FLASH->IAPSR & (uint8_t)0x08)); //等待解锁操作
System_Delay(200);
uPassWord =(uint8_t)I2C_ReadByte(SLAVE_BLOCK_START_ADDRESS,SLAVE_START_ADDRESS);
System_Delay(10);
uFlash = (uint8_t)FLASH_ReadByte(MCU_EEPROM_START);
System_Delay(200);
while (FLASH_GetFlagStatus( FLASH_FLAG_EOP) == SET);
}
if((uFlash^uPassWord) == 0)
{
LCD_Cmd(ENABLE);
PassWordBrand.uStatus = VERIFY_SUCESS;
return 0;
}
return 1;
}
/*******************************************************************
* 函数名:ReadPassWDMode
* 输 入:void
* 输 出:void
* 功 能:读密码牌操作
********************************************************************/
uint8_t ReadPassWDMode()
{
if(BUTTON_DOWN(GPIOC,PASSWORD_BRAND))
{
ReadPasswdBrand();
if(PassWordBrand.uStatus != VERIFY_FAILD)
{
PassWordBrand.Start_Flick = SET;
if(System_AutoCheck())
{
MainMenu.uMenu = NO_OPERATION_MENU;
PassWordBrand.uStatus = VERIFY_FAILD;
PassWordBrand.Start_Flick = RESET;
InputDevice.uProcType = NONE_PROCESS; //
}
}
}
else
{
/* 密码牌插入不稳 */
Frame.uEvent = SYSTEM_TESTING_ERROR; //提示密码牌出错
Frame.uValuer.uError = ERROR_E4;
LCD_ClearScreen();
InputDevice.uProcType = NONE_PROCESS; //
return 1;
}
return 0;
}
/*******************************************************************
* 函数名:TestBoolMode
* 输 入:void
* 输 出:void
* 功 能:读密码牌操作
********************************************************************/
void TestBoolMode()
{
if(BUTTON_DOWN(GPIOG,TESTING_BOTTLET))
{
my_test();
if(BottlerOpt.BottlerPriority == SET)
{
BottlerOpt.BottlerPriority = RESET;
LCD_ClearScreen();
}
}
else
{
Frame.uEvent = SYSTEM_BLOTTER_OUT;
InputDevice.uPriority = NO_PRIORITY;
MainMenu.uMenu = NO_OPERATION_MENU;
}
}
/*******************************************************************
* 函数名:void System_AutoCheck()
* 输 入:void
* 输 出:void
* 功 能:所有血糖值记录为空
********************************************************************/
uint8_t System_AutoCheck()
{
static uint8_t Calc = 0;
Display_DataValuer(DISPLAY_BIT_NUM_1,(uint8_t)Calc);
Display_DataValuer(DISPLAY_BIT_NUM_2,(uint8_t)Calc);
Display_DataValuer(DISPLAY_BIT_NUM_3,(uint8_t)Calc);
Display_DataValuer(DISPLAY_BIT_NUM_4,(uint8_t)Calc);
Display_DataValuer(DISPLAY_BIT_NUM_5,(uint8_t)Calc);
Display_DataValuer(DISPLAY_BIT_NUM_6,(uint8_t)Calc);
Display_DataValuer(DISPLAY_BIT_NUM_7,(uint8_t)Calc);
Display_DataValuer(DISPLAY_BIT_NUM_8,(uint8_t)Calc);
Display_DataValuer(DISPLAY_BIT_NUM_9,(uint8_t)Calc);
Display_DataValuer(DISPLAY_BIT_NUM_10,(uint8_t)Calc);
Display_DataValuer(DISPLAY_BIT_NUM_11,(uint8_t)Calc);
Display_DataValuer(DISPLAY_BIT_NUM_12,(uint8_t)Calc);
Display_DataValuer(DISPLAY_BIT_NUM_13,(uint8_t)Calc);
Display_DataValuer(DISPLAY_BIT_NUM_14,(uint8_t)Calc);
Display_DataValuer(DISPLAY_BIT_NUM_15,(uint8_t)Calc);
Display_DataValuer(DISPLAY_BIT_NUM_16,(uint8_t)Calc);
if(PassWordBrand.Flick_Calc == SET)
{
PassWordBrand.Flick_Calc = RESET;
Calc++;
if(Calc == 0x0A)
{
Calc = 0x00;
PassWordBrand.DspCalc =0;
PassWordBrand.Start_Flick = RESET;
return 1;
}
Screen_ClearPostion(DISPLAY_BIT_NUM_1);
Screen_ClearPostion(DISPLAY_BIT_NUM_2);
Screen_ClearPostion(DISPLAY_BIT_NUM_3);
Screen_ClearPostion(DISPLAY_BIT_NUM_4);
Screen_ClearPostion(DISPLAY_BIT_NUM_5);
Screen_ClearPostion(DISPLAY_BIT_NUM_6);
Screen_ClearPostion(DISPLAY_BIT_NUM_7);
Screen_ClearPostion(DISPLAY_BIT_NUM_8);
Screen_ClearPostion(DISPLAY_BIT_NUM_9);
Screen_ClearPostion(DISPLAY_BIT_NUM_10);
Screen_ClearPostion(DISPLAY_BIT_NUM_11);
Screen_ClearPostion(DISPLAY_BIT_NUM_12);
Screen_ClearPostion(DISPLAY_BIT_NUM_13);
Screen_ClearPostion(DISPLAY_BIT_NUM_14);
Screen_ClearPostion(DISPLAY_BIT_NUM_15);
Screen_ClearPostion(DISPLAY_BIT_NUM_16);
}
return 0;
}
/***************************************************************
* 函数名:USART_Config()
* 输入 :void
* 输出 :void
* 功能 :初始化串口
****************************************************************/
static void USART_Config(void)
{
/* 配置USART3外围时钟源 */
CLK_PeripheralClockConfig(CLK_Peripheral_USART3, ENABLE);
/* 配置RX,TX引脚为上拉 */
GPIO_ExternalPullUpConfig(GPIOG, GPIO_Pin_0|GPIO_Pin_1, ENABLE);
/* 初始化USART2,波特率,控制和校验 */
USART_Init(USART3,(uint32_t)9600, USART_WordLength_8b, USART_StopBits_1,
USART_Parity_No, (USART_Mode_TypeDef)(USART_Mode_Tx | USART_Mode_Rx));
/* 采用中断方式接收 */
// enableInterrupts();
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
/* 启动USART3 */
USART_Cmd(USART3, ENABLE);
}
/***************************************************************
* 函数名:TIM4_Config
* 输入 :void
* 输出 :void
* 功能 :初始化定时器
****************************************************************/
static void TIM4_Config(void)
{
CLK_PeripheralClockConfig(CLK_Peripheral_TIM4, ENABLE);
TIM4_TimeBaseInit(TIM4_Prescaler_16384, 1); //定时1S
/* Enable TIM4_IT clock */
TIM4_ITConfig(TIM4_IT_Update,ENABLE);
TIM4_Cmd(ENABLE);
}
/***************************************************************
* 函数名:LCD_Config
* 输入 :void
* 输出 :void
* 功能 :初始化LCD显示器
****************************************************************/
static void LCD_RTCConfig(void)
{
/* Enable LSE */
CLK_LSEConfig(CLK_LSE_ON);
/* Enable LCD clock */
CLK_PeripheralClockConfig(CLK_Peripheral_LCD, ENABLE);
CLK_RTCClockConfig(CLK_RTCCLKSource_LSE, CLK_RTCCLKDiv_1);
/* Enable RTC clock */
CLK_PeripheralClockConfig(CLK_Peripheral_RTC, ENABLE);
}
/**************************************************************************************
* 函数原型:void Read_RTCTimes()
* 输 入:void
* 输 出:void
* 功 能:读取时钟
* 描 述:
***************************************************************************************/
void Read_RTCTimes()
{
do{
while (RTC_WaitForSynchro() != SUCCESS);
RTC_GetTime(RTC_Format_BIN, &RTC_TimeStr);
RTC_GetDate(RTC_Format_BIN, &RTC_DateStr);
Frame.uValuer.uTimes.uFrame_Year = RTC_DateStr.RTC_Year;
Frame.uValuer.uTimes.uFrame_Month = (((uint8_t)RTC_DateStr.RTC_Month & 0xF0)>>4)*10+((uint8_t)RTC_DateStr.RTC_Month &0x0F);
Frame.uValuer.uTimes.uFrame_Date = RTC_DateStr.RTC_Date;
Frame.uValuer.uTimes.uFrame_Hours= RTC_TimeStr.RTC_Hours;
Frame.uValuer.uTimes.uFrame_Minutes = RTC_TimeStr.RTC_Minutes;
}
while(0);
}
/****************************************************
* 函数名:Time_Setting
* 输 入:void
* 输 出:uint8_t
* 功 能:时间校验检查
* 描 述:
*****************************************************/
uint8_t Time_Setting(void)
{
RTC_DateStr.RTC_Year = Frame.uValuer.uTimes.uFrame_Year;
RTC_DateStr.RTC_Month = (RTC_Month_TypeDef)Frame.uValuer.uTimes.uFrame_Month;
RTC_DateStr.RTC_Date = Frame.uValuer.uTimes.uFrame_Date;
RTC_TimeStr.RTC_Hours = Frame.uValuer.uTimes.uFrame_Hours;
RTC_TimeStr.RTC_Minutes = Frame.uValuer.uTimes.uFrame_Minutes;
RTC_TimeStr.RTC_Seconds = (uint8_t)DATA_EMPTY;
RTC_SetTime(RTC_Format_BIN, &RTC_TimeStr);
RTC_SetDate(RTC_Format_BIN, &RTC_DateStr);
while (RTC_WaitForSynchro() != SUCCESS);
RTC_GetTime(RTC_Format_BIN, &RTC_TimeStr);
RTC_GetDate(RTC_Format_BIN, &RTC_DateStr);
if(RTC_DateStr.RTC_Year > 100)
return 0;
if((((uint8_t)RTC_DateStr.RTC_Month>>4)&0x0F)*10 + ((uint8_t)RTC_DateStr.RTC_Month & 0x0F) > 12)
return 0;
if(RTC_DateStr.RTC_Date > 31)
return 0;
if(RTC_TimeStr.RTC_Hours > 24)
return 0;
if( RTC_TimeStr.RTC_Minutes > 60)
return 0;
return 1;
}
/******************************************************************************************
* 函数原型:uint8_t Read_RecodeData(uint32_t paddr,uint8_t *uData)
* 输 入:uint8_t paddr - 数据记录首地址
uint8_t *uData - 读出数据缓存
* 输 出:uint8_t - 读出数据情况,如果成功返回读出数据记录长度、
否则为0
* 功 能: 实现一次数据记录的读取操作
* 描 述:
******************************************************************************************/
uint8_t Read_RecodeData(uint32_t paddr,uint8_t *uData)
{
static uint8_t upackge_index = 0x00;
static uint32_t pStart_addr;
uint8_t Empty_Calc = 0x00;
uint8_t uindex = 0x00;
uint8_t Package_Mum = PACKAGE_SEND_MAX;
if(upackge_index == DATA_EMPTY)
pStart_addr = paddr;
if((uData[DATA_START]-upackge_index) == 0x01) //最后一次数据读取判断
{
if(Frame.uContrl.uFrame_LastLen !=DATA_EMPTY) //如果是不完整的发送包个数
Package_Mum = Frame.uContrl.uFrame_LastLen;
Frame.uContrl.uFrame_Next = RESET; //清除后续包标志
}
for(;uindex < Package_Mum*RECODE_SIGEN_LEN;uindex++)
{
if(DATA_EMPTY == *((PointerAttr uint8_t*)(uint16_t)pStart_addr+uindex)) //判断数据记录是否为空
Empty_Calc++;
if(RECODE_SIGEN_LEN <= Empty_Calc ) //如果有一条记录为空
return 0;
if((uindex != 0) &&(uindex % RECODE_SIGEN_LEN ==0))
Empty_Calc = 0x00;
uData[FRAME_START+uindex] = *((PointerAttr uint8_t *)(uint16_t)pStart_addr+ uindex); // 读取数据到缓冲buffer
}
upackge_index++;
uData[DATA_START+0x01] = upackge_index; //当前读取次数
uData[FRAME_START-0x01] = uindex / RECODE_SIGEN_LEN ; //当前读取包个数
pStart_addr += (uint32_t)READ_BUFF_MAX; //保存读取地址
if(Frame.uContrl.uFrame_Next == RESET)
upackge_index = 0x00;
Frame.uContrl.uFrame_DataLen = uindex;
return 1;
}
/********************************************************************************************
* 函数原型:uint8_t Recode_Header(uint32_t paddr,uint8_t *uData)
* 输 入:uint8_t paddr - 记录头首地址 (数据包个数地址)
uint8_t *uData - 读出数据缓存
* 输 出:uint8_t - 读取情况,如果为空返回1 ,如果为0表示记录不为空
* 功 能:读取数据记录头信息
* 描 述:
********************************************************************************************/
uint8_t Recode_Header(uint32_t paddr,uint8_t *uData)
{
uint8_t Send_index = (uint8_t)(*((PointerAttr uint8_t*)((uint16_t)paddr))/PACKAGE_SEND_MAX);
if(*((PointerAttr uint8_t *)((uint16_t)paddr)) == 0x00)
return 0;
if((*((PointerAttr uint8_t*)((uint16_t)paddr))%PACKAGE_SEND_MAX))
{
Send_index++;
Frame.uContrl.uFrame_LastLen = (uint8_t)*((PointerAttr uint8_t*)((uint16_t)paddr))%PACKAGE_SEND_MAX;
}
uData[DATA_START] = Send_index;
if(uData[DATA_START] > 0x01)
Frame.uContrl.uFrame_Next = SET;
return 1;
}
/********************************************************************************************
* 函数原型:uint8_t Recode_Header(uint32_t paddr,uint8_t *uData)
* 输 入:uint8_t paddr - 记录头首地址 (数据包个数地址)
uint8_t *uData - 读出数据缓存
* 输 出:uint8_t - 读取情况,如果为空返回1 ,如果为0表示记录不为空
* 功 能:读取数据记录头信息
* 描 述:
********************************************************************************************/
void System_EventProcess()
{
/* 被动发送测试
*****************************************************************
*/
/* 测试连接与读取ID信息 !*/
if(Frame.uAction.uEvent == READ_STATE)
{
Frame.uAction.uEvent = INVALID_ACTION;
/* 读取时间 */
Read_RTCTimes();
Frame.uAction.uResult = ACTION_SUCCESS;
Frame.uEvent = READSYS_STATE_FINSHED;
}
/* 测试清除数据 ! */
if(Frame.uAction.uEvent == ERASE_RECODE)
{
Frame.uAction.uEvent = INVALID_ACTION;
/* .........进行清除操作........... */
Frame.uAction.uResult = ACTION_SUCCESS;
Frame.uEvent = ERASE_RECODE_FINSHED;
}
/* 测试设置时间 ! */
if(Frame.uAction.uEvent == SETING_TIME)
{
Frame.uAction.uEvent = INVALID_ACTION;
if(Time_Setting())
Frame.uAction.uResult = ACTION_SUCCESS;
Frame.uEvent = SETING_TIME_FINSHED;
}
/* 读取血糖测试结果 !*/
if(Frame.uAction.uEvent == READ_SESULT)
{
Frame.uAction.uEvent = INVALID_ACTION;
/* 测试模式读取血糖测试结果 */
Frame.uValuer.uTestMode =TESTING_MODE;
……………………
…………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
于STM8L低功耗系列芯片,开发一款智能手持血糖监测设备的源码.7z
(158.68 KB, 下载次数: 24)
2019-2-20 16:37 上传
点击文件名下载附件
下载积分: 黑币 -5
作者:
admin
时间:
2019-2-20 16:38
本帖需要重新编辑补全电路原理图,源码,详细说明与图片即可获得100+黑币(帖子下方有编辑按钮)
作者:
黄焖鸡米饭1
时间:
2019-2-20 17:10
点错了,,。。没想下载。。。。尴尬
作者:
黄焖鸡米饭1
时间:
2019-2-20 17:11
admin 发表于 2019-2-20 16:38
本帖需要重新编辑补全电路原理图,源码,详细说明与图片即可获得100+黑币(帖子下方有编辑按钮)
是我发的无效了么,我说我点错了,并不想下载尴尬啊,我的黑币
作者:
admin
时间:
2019-2-20 19:35
缺原理图
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1