float Get_DS18B20_Temperature(void) /** * \brief 主机向Ds18b20读温度值 * * \param None * * \retval Temperature */ { uint8_t TL; uint16_t TH; float Temperature; DS18B20_Init(); DS18B20_WriteOneByte(SKIP_ROM); //跳过读序列号的操作 DS18B20_WriteOneByte(CONVERT_T); //启动温度转换 DS18B20_DelayXus(20); DS18B20_Init(); DS18B20_WriteOneByte(SKIP_ROM); //跳过读序列号的操作 DS18B20_WriteOneByte(READ_SCRATCHPAD); //读温度寄存器,共9个byte,前两个byte为温度值 TL = DS18B20_ReadOneByte(); //TL存低字节 TH = DS18B20_ReadOneByte(); //TH存高字节 // TH <<= 4; // TH += (TL & 0xF0) >> 4; // Temperature = TH; TH <<= 8; TH |= TL; Temperature = TH * 0.0625; return Temperature; }
/* * DS18B20获取温度函数 * 输入参数: 无 * 输出参数: 无 * 返回参数: 无 * */ void DS18B20_GetTem(void) { unsigned char tem_h,tem_l; //温度高位字节及低位字节,最后存储整数部分和小数部分的数据 unsigned char flag=0; //温度正负标记,正为0,负为1 unsigned short int t; DS18B20_Init(); //DS18B20复位 DS18B20_Write(SKIP_ROM); //跳过ROM匹配 DS18B20_Write(RD_SCRATCHPAD); //写入读9字节命令 tem_l = DS18B20_Read(); //读温度低位。第一字节 tem_h = DS18B20_Read(); //读温度高位,第二字节 /* 判断RAM中存储的温度正负 并提取出符号位和真实的数据 */ if(tem_h & 0x80) { flag = 1; //温度为负 t = tem_l+tem_h<<8; t = ~(t-1); tem_l = t & 0x0f; //取小数部分 tem_h = (t & 0x0ff0)>>4; //取整数部分 }
/********以下是读取温度值函数********/ Ds18B20_GetTemperture(void) { DS18B20_Init(); //DS18B20初始化 if(yes0==0) //若yes0为0,说明DS18B20正常 { DS18B20_WriteOneByte(0xCC); // 跳过读序号列号的操作 DS18B20_WriteOneByte(0x44); // 启动温度转换 Lcd_delay(200); //调用显示函数延时,等待A/D转换结束,分辨率为12位时需延时750ms以上 DS18B20_Init(); DS18B20_WriteOneByte(0xCC); //跳过读序号列号的操作 DS18B20_WriteOneByte(0xBE); //读取温度寄存器 TL = DS18B20_ReadOneByte(); //温度低8位 TH= DS18B20_ReadOneByte(); //温度高8位 } else { DS18B20_display_error(); } }
int main() { /* Initialize system */ SystemInit(); /* Initialize delay */ TM_DELAY_Init(); // Pin GPIO H4 for use by logic analyser. ConfigureDebugOutputPin(); USART3_Configuration(); printf("\r***************************************************************\r"); printf("* DS18B20 Temperature Controller *\r"); printf("***************************************************************\r"); // Setup the GPIO port and pin to talk to OneWire devices. DS18B20_Init(); //Search for devices and show their ROM codes. ShowROMCodesOfDevices(); printf(" \r"); char buffer[80]; while (1) { // Read the temperature. Blocks the processor for 700us or so. //BlockAndReadRawTemperature(); // Read the temperature. Non-blocking. DS18B20ReadTemperature(); if (DS18B20Status == TEMPERATURE_AVAILABLE) { //float celsius = (float)roundf(GetTemperatureCelsius() * 100) / 100; float celsius = GetTemperatureCelsius(); printf("Temp: %s\r", FormatFloatToString(celsius, buffer, 2)); } Delayms(500); } }
int main() { u16 PM25Val; short temperature; SysTick_Init(); pc1.baud(115200); ESP8266_Init(); while(1){ PM25Val=GP2Y1010auGetPM25(); pc1.printf("Dust Value is: %d ug/m3\r\n",PM25Val); ESP8266_Ds18b20UpdateLeWei50(PM25Val); } pc1.printf("Start DS18B20 Init ..."); while(DS18B20_Init()) { wait_ms(1000); pc1.printf("DS18B20 Init Ing..."); } while(1){ temperature=DS18B20_Get_Temp(); pc1.printf("Get Temperature : %.1f\n",temperature/10.0); wait_ms(1000); } }
/* * DS18B20 转换温度函数 * 输入参数: 无 * 输出参数: 无 * 返回参数: 无 * */ void DS18B20_SendConvert(void) { DS18B20_Init(); //复位18B20 DS18B20_Write(SKIP_ROM); //发出跳过ROM匹配操作 DS18B20_Write(CONVERT_T); //启动温度转换 }
void main(void) { /*----------IO口设置----------*/ GPIO_Init(ADDR_LOW_PORT, GPIO_Pin_All, GPIO_Mode_Out_PP_Low_Slow); //8位地址 GPIO_Init(ADDR_HIGH_PORT0, ADDR_HIGH_PIN0, GPIO_Mode_Out_PP_Low_Slow); //未使用口设置为输出低电平 //P1.3/mode0 - 模块输入睡眠,stm8输出睡眠 GPIO_Init( MODE0_PORT, MODE0_PIN, GPIO_Mode_Out_PP_Low_Slow); //P1.5/mode1 - 模块输出睡眠,stm8输入睡眠 //Zigbee透传模块输出给stm8的唤醒信号为高电平,并在10ms后开始发送串口信号 //由于stm8输入无内部下拉选项,因此只能设置为浮动输入 //当不接Zigbee模块单独进行stm8程序调试时,浮动输入将可能导致持续发生中断,所以请务必接入Zigbee模块或在不接入模块时改为输入上拉 GPIO_Init( MODE1_PORT, MODE1_PIN, GPIO_Mode_In_FL_IT); EXTI_SetPinSensitivity(EXTI_Pin_3, EXTI_Trigger_Rising); GPIO_Init(SENSOR_DATA_PORT, SENSOR_DATA_PIN, GPIO_Mode_Out_PP_High_Fast); //传感器数据口拉高 //等效为如下配置 //SENSOR_DATA_PORT->ODR |= SENSOR_DATA_PIN; //输出高电平 //SENSOR_DATA_PORT->CR1 |= SENSOR_DATA_PIN; //推挽输出 //SENSOR_DATA_PORT->CR2 &= (uint8_t)(~(SENSOR_DATA_PIN)); //10MHz高速输出 //SENSOR_DATA_PORT->DDR |= SENSOR_DATA_PIN; //设置为输出 //GPIO_Init(SENSOR_DATA_PORT, SENSOR_DATA_PIN, GPIO_Mode_In_PU_No_IT); //传感器数据口输入上拉无中断 //等效为如下配置 //SENSOR_DATA_PORT->ODR |= SENSOR_DATA_PIN; //输出高电平,此项在输入时无关紧要 //SENSOR_DATA_PORT->CR1 |= SENSOR_DATA_PIN; //输入上拉 //SENSOR_DATA_PORT->CR2 &= (uint8_t)(~(SENSOR_DATA_PIN)); //无中断 //SENSOR_DATA_PORT->DDR &= (uint8_t)(~(SENSOR_DATA_PIN)); //设置为输入 //由此可见,当进行18B20的单总线输入输出切换时,只需要最后一行配置DDR即可以高速切换,这样就可以精确控制时间 /*----------系统周期设置与内部模块使能----------*/ CLK_DeInit(); CLK_PeripheralClockConfig(CLK_Peripheral_AWU, ENABLE); //使能唤醒 CLK_MasterPrescalerConfig(CLK_MasterPrescaler_HSIDiv8); //时钟8分频,2MHz /*----------唤醒初始化----------*/ AWU_DeInit(); /*----------串口初始化----------*/ CLK_PeripheralClockConfig(CLK_Peripheral_USART, ENABLE); //使能串口 GPIO_ExternalPullUpConfig(GPIOC,GPIO_Pin_2|GPIO_Pin_3, ENABLE); //拉高电平 USART_DeInit(); USART_Init(115200, //波特率115200 USART_WordLength_8D, //8位数据位 USART_StopBits_1, //1位停止位 USART_Parity_No, //无校验 USART_Mode_Rx | USART_Mode_Tx); //接收和发送使能 //USART_ITConfig(USART_IT_TXE, ENABLE); //使能发送中断 USART_Cmd(ENABLE); //串口开始工作 /*----------看门狗初始化----------*/ //注意!!看门狗的最长喂狗时限仅1~2秒,而本程序中单片机休眠时间最长设置为30秒 //所以需要将Option Byte中的OPT4由默认的0x00改为0x01,以使休眠时看门狗暂停 //Option Byte无法在程序中修改,只能通过烧写软件如STVP在烧写时由SWIM协议外部写入 //因此在调试时看门狗功能无法实现 //由SWIM外部烧写时请自行宏定义WATCHDOG以使看门狗生效 #ifdef WATCHDOG IWDG_Enable(); IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); IWDG_SetPrescaler(IWDG_Prescaler_256); //看门狗时限设为最长的1724.63ms IWDG_SetReload(0xFF); IWDG_ReloadCounter(); #endif /*----------以下进行Zigbee串口透传模块地址的设置----------*/ //我们以STM8L 96bit唯一序列号中的8bit作为地址低位,地址高3bit放空为0x000,实际应用中可以采用拨码开关等方式进行设定 //注意!如果采用IO口设置地址,IO口电平很大程度将影响设备功耗,为此做如下考虑 //Zigbee串口透传模块的输入为内部下拉,如STM8L长期将IO口置于高电平将有近毫安级的电流损耗 //因此Zigbee模块在开机后1秒时读入IO口设置地址,其余时间应将IO口置于低电平以降低功耗(见模块手册) //对于STM8L而言应在开机时设置地址IO口,并在0.5秒后将IO口恢复低电平 //如采用拨码设置地址的方式,则首先应拨好设置地址,然后上电,并在0.5秒后将开关拨回至0 //如果采用串口设置地址模式,则将地址设置IO口全部下拉,写入串口设置地址值后重启模块即可以完成地址设置 AddrHi=0; //地址高位置0 注意!!本程序放空了模块地址高位设置口,故地址高位为0,如需改为自己的程序请记得设置该地址并在下面的程序中设置对应的地址IO FLASH_SetProgrammingTime(FLASH_ProgramTime_Standard); FLASH_Unlock(FLASH_MemType_Program); //AddrLo=FLASH_ReadByte(0x4926); //采用X-coordinator AddrLo=FLASH_ReadByte(0x4928); //采用Y-coordinator //AddrLo=(FLASH_ReadByte(0x4926)<<4) | (FLASH_ReadByte(0x4928)&0x0F); //X-coordinator和Y-coordinator各占4bit FLASH_Lock(FLASH_MemType_Program); Addr = ((u16)AddrHi<<8) | AddrLo; //将高低位地址组合成完整地址 //等待模块初始化完成以能响应串口设置命令 //注意!!这里 for(u8 i=0; i<6; i++) { Delay(0xFFFF); //每个Delay约200ms,总延时1秒以上,这里要有足量等待时间,因为模块上电一段时间后串口才开始工作接收数据 } #ifndef USE_SEC_ADDR //未定义使用串口设置方案,则采用IO口设置方案 //GPIO_Write(ADDR_HIGH_PORT, AddrHi); //注意!!本程序放空了模块地址高位设置口,所以这里无需再拉IO口,如改为自己的程序请记得设置高位的地址并在此设置IO GPIO_Write(ADDR_LOW_PORT, AddrLo); //写入低8位地址,高3位放空 for(u8 i=0; i<3; i++) { Delay(0xFFFF); //每个Delay约200ms,总延时0.5秒以上,因为在0.5秒时读入地址IO口,之后地址IO口状态不影响地址设置 } //GPIO_Write(ADDR_HIGH_PORT, 0); GPIO_Write(ADDR_LOW_PORT, 0x00); //将地址IO口置回0以降低功耗 #else //定义了串口设置地址方案,采用串口设置地址 //采用串口设置地址方式需下拉所有地址IO口使之为0x0000 //本程序IO口初始化时均为下拉低电平,无需更改电平,注意如果拉高任何地址IO口,则串口地址无效,自动采用IO口所设置的地址 //GPIO_Write(ADDR_LOW_PORT, 0); //地址低位写入低电平,初始化已为低电平,无需写入 //GPIO_Write(ADDR_HIGH_PORT, 0); //地址高位写入低电平,初始化已为低电平,无需写入 //以下将地址转换为串口设置命令字符串,首先输入设置命令UNI_SEC_ADDR和命令与设置值之间的空格 UARTSendDataBuf[0]='U';UARTSendDataBuf[1]='N';UARTSendDataBuf[2]='I';UARTSendDataBuf[3]='_';UARTSendDataBuf[4]='S'; UARTSendDataBuf[5]='E';UARTSendDataBuf[6]='C';UARTSendDataBuf[7]='_';UARTSendDataBuf[8]='A';UARTSendDataBuf[9]='D'; UARTSendDataBuf[10]='D';UARTSendDataBuf[11]='R';UARTSendDataBuf[12]=' '; //然后将13bit地址转换为四字节字符串,如0x0789转化为“1929”,0x0089转化为“0137”,并将值填入UARTSendDataBuf[13]~UARTSendDataBuf[16] SettingTemp=Addr; for(u8 i=0; i<4; i++) { UARTSendDataBuf[16-i] = '0' + (SettingTemp % 10); SettingTemp /= 10; } //发送设置地址命令 UART_Send_Data(UARTSendDataBuf, 17); Delay(0x3000); //稍作等待 #endif /*----------以下进行其他参数设置,请在35行处取消需要设置值的#define注释并设置相应值----------*/ #ifdef SETTING_PANID //PANID设置,注意设置的PANID要与主机和路由器一致才可正常工作 assert_param(SETTING_PANID>=1 && SETTING_PANID<=65535); UARTSendDataBuf[0]='P';UARTSendDataBuf[1]='A';UARTSendDataBuf[2]='N';UARTSendDataBuf[3]='I';UARTSendDataBuf[4]='D'; UARTSendDataBuf[5]=' '; //然后将两字节PANID转换为五字节字符串,并将值填入UARTSendDataBuf[6]~UARTSendDataBuf[10] SettingTemp=SETTING_PANID; for(u8 i=0; i<5; i++) { UARTSendDataBuf[10-i] = '0' + (SettingTemp % 10); SettingTemp /= 10; } //发送设置命令 UART_Send_Data(UARTSendDataBuf, 11); Delay(0x3000); //稍作等待 #endif //SETTING_PANID #ifdef SETTING_TX_POWER //TX_POWER发射功率设置 assert_param(SETTING_TX_POWER>=0 && SETTING_TX_POWER<=21); UARTSendDataBuf[0]='T';UARTSendDataBuf[1]='X';UARTSendDataBuf[2]='_';UARTSendDataBuf[3]='P';UARTSendDataBuf[4]='O'; UARTSendDataBuf[5]='W';UARTSendDataBuf[6]='E';UARTSendDataBuf[7]='R';UARTSendDataBuf[8]=' '; //然后将TX_POWER转换为两字节字符串,并将值填入UARTSendDataBuf[9]~UARTSendDataBuf[10] SettingTemp=SETTING_TX_POWER; for(u8 i=0; i<2; i++) { UARTSendDataBuf[10-i] = '0' + (SettingTemp % 10); SettingTemp /= 10; } //发送设置命令 UART_Send_Data(UARTSendDataBuf, 11); Delay(0x3000); //稍作等待 #endif //SETTING_TX_POWER #ifdef SETTING_CHANNEL //CHANNEL设置,注意设置的CHANNEL要与主机和路由器一致才可正常工作 assert_param(SETTING_CHANNEL>=2048 && SETTING_CHANNEL<=134215680); UARTSendDataBuf[0]='C';UARTSendDataBuf[1]='H';UARTSendDataBuf[2]='A';UARTSendDataBuf[3]='N';UARTSendDataBuf[4]='N'; UARTSendDataBuf[5]='E';UARTSendDataBuf[6]='L';UARTSendDataBuf[7]=' '; //然后将CHANNEL转换为十字节字符串,并将值填入UARTSendDataBuf[8]~UARTSendDataBuf[17] SettingTemp=SETTING_CHANNEL; for(u8 i=0; i<10; i++) { UARTSendDataBuf[17-i] = '0' + (SettingTemp % 10); SettingTemp /= 10; } //发送设置命令 UART_Send_Data(UARTSendDataBuf, 18); Delay(0x3000); //稍作等待 #endif //SETTING_CHANNEL #ifdef SETTING_POLL_RATE //POLL_RATE终端定期唤醒查询数据时限 assert_param(SETTING_POLL_RATE>=0 && SETTING_POLL_RATE<=65535); UARTSendDataBuf[0]='P';UARTSendDataBuf[1]='O';UARTSendDataBuf[2]='L';UARTSendDataBuf[3]='L';UARTSendDataBuf[4]='_'; UARTSendDataBuf[5]='R';UARTSendDataBuf[6]='A';UARTSendDataBuf[7]='T';UARTSendDataBuf[8]='E';UARTSendDataBuf[9]=' '; //然后将POLL_RATE转换为五字节字符串,并将值填入UARTSendDataBuf[10]~UARTSendDataBuf[14] SettingTemp=SETTING_POLL_RATE; for(u8 i=0; i<5; i++) { UARTSendDataBuf[14-i] = '0' + (SettingTemp % 10); SettingTemp /= 10; } //发送设置命令 UART_Send_Data(UARTSendDataBuf, 15); Delay(0x3000); //稍作等待 #endif //SETTING_POLL_RATE //写入重启模块命令PW_RESET 1 UARTSendDataBuf[0]='P';UARTSendDataBuf[1]='W';UARTSendDataBuf[2]='_';UARTSendDataBuf[3]='R';UARTSendDataBuf[4]='E'; UARTSendDataBuf[5]='S';UARTSendDataBuf[6]='E';UARTSendDataBuf[7]='T';UARTSendDataBuf[8]=' ';UARTSendDataBuf[9]='1'; //发送重启命令 UART_Send_Data(UARTSendDataBuf, 10); //等待模块重启,重启0.5秒时读入地址设置IO口为0x0000,进入串口设置地址模式,读取刚才我们串口所设置的地址并工作在该地址 for(u8 i=0; i<6; i++) { Delay(0xFFFF); //每个Delay约200ms,总延时1秒以上,这里要有足量等待时间,因为模块上电一段时间后串口才开始工作接收数据 } //以下进行18B20采样精度设置 DS18B20_Init(); DS18B20_Write(0xCC); //跳过ROM操作 DS18B20_Write(0xBE); //读配置 //读出TH,TL值以便设置时将其原样写入不进行改变 Temprature=DS18B20_Read(); //低8位 Temprature=Temprature | (DS18B20_Read()<<8); //高8位 TH=DS18B20_Read(); TL=DS18B20_Read(); Config=DS18B20_Read(); DS18B20_Init(); DS18B20_Write(0xCC); //跳过ROM操作 DS18B20_Write(0x4E); //写配置 DS18B20_Write(TH); //原样写入不改变 DS18B20_Write(TL); //原样写入不改变 DS18B20_Write(0x1F); //采用较低分辨率能大幅降低功耗 1F:9位,93.75ms 3F:10位,187.5ms 5F:11位,375ms 7F:12位,750ms #ifdef UI_STRING //字符串输出界面 //格式 ID:1234 T:+025.0 //0~3,AA XX XX 55,目的地址 //4~6, 3字节头 //7~10, 4字节地址 //11~13, 3字节中 //14,符号位 //15~17,整数位 //18,小数点 //19,小数位 //20,1字节尾 UARTSendDataBuf[0]=0xAA;UARTSendDataBuf[1]=0x00;UARTSendDataBuf[2]=0x00;UARTSendDataBuf[3]=0x55; UARTSendDataBuf[4]='I';UARTSendDataBuf[5]='D';UARTSendDataBuf[6]=':'; //将本机地址转换为十字节字符串,并将值填入UARTSendDataBuf[10]~UARTSendDataBuf[19] SettingTemp=Addr; for(u8 i=0; i<4; i++) { UARTSendDataBuf[10-i] = '0' + (SettingTemp % 10); SettingTemp /= 10; } //将头部的所有0替换为空格 i=7; while(UARTSendDataBuf[i]=='0') { UARTSendDataBuf[i++]=' '; } UARTSendDataBuf[11]=' ';UARTSendDataBuf[12]='T';UARTSendDataBuf[13]=':'; UARTSendDataBuf[18]='.'; UARTSendDataBuf[20]=' '; #endif disableInterrupts(); /* Infinite loop */ while (1) { #ifdef WATCHDOG IWDG_ReloadCounter(); //喂狗 #endif if(WakeCount<=0) //每WORK_TO_WAKE_RATIO次唤醒采集一次传感器数据并上传,之所以采用初值-1这里<=0后面++并%WORK_TO_WAKE_RATIO的方式,是为了在开机时能连采两次使传感器工作正常 { DS18B20_Init(); DS18B20_Write(0xCC); //跳过ROM操作 DS18B20_Write(0x44); //温度转换 //9位分辨率93.75ms采样时间情况下,进入睡眠128ms,等待18B20采样完成 //注意!如果提采样高分辨率会延长采样时间,此时应延长睡眠时间使之大于采样时间,否则会出错 enableInterrupts(); AWU_Init(AWU_Timebase_128ms); AWU_ReInitCounter(); AWU_Cmd(ENABLE); halt(); disableInterrupts(); #ifdef WATCHDOG IWDG_ReloadCounter(); //喂狗 #endif while(GPIO_ReadInputDataBit(SENSOR_DATA_PORT, SENSOR_DATA_PIN)==RESET); //如18B20还未采样完成则等待 DS18B20_Init(); DS18B20_Write(0xCC); //跳过ROM操作 DS18B20_Write(0xBE); //读取RAM Temprature=DS18B20_Read(); //低8位 Temprature=Temprature | (DS18B20_Read()<<8); //高8位 TH=DS18B20_Read(); TL=DS18B20_Read(); Config=DS18B20_Read(); DS18B20_Init(); //reset,终止读写其他寄存器 #ifndef UI_STRING //将采集到的温度数据发送到主机 UARTSendDataBuf[0]=0xAA; //4字节目的地址包头,0xAA 目的地址高位 目的地址低位 0x55,主机目的地址高低位均为0x00 UARTSendDataBuf[1]=0x00; UARTSendDataBuf[2]=0x00; UARTSendDataBuf[3]=0x55; UARTSendDataBuf[4]=AddrHi; //发送给主机本机地址以方便主机的寻址,地址高位,这里我们放空了地址高位,模块的3位地址高位默认下拉设置为0 UARTSendDataBuf[5]=AddrLo; //发送给主机本机地址低位 UARTSendDataBuf[6]=(u8)(Temprature>>8); //温度高位 UARTSendDataBuf[7]=(u8)(Temprature&0x00FF); //温度低位 UART_Send_Data(UARTSendDataBuf, 8); //将数据发送到主机 #else //字符串格式 UARTSendDataBuf[14]='+'; if(Temprature & 0x8000) //最高位为1,负的,取反加一 { UARTSendDataBuf[14]='-'; Temprature = (~Temprature)+1; } //小数部分 UARTSendDataBuf[19]='0'; if(Temprature & 0x000F) { UARTSendDataBuf[19]='5'; } //整数部分 SettingTemp=Temprature>>4; for(u8 i=0; i<3; i++) { UARTSendDataBuf[17-i] = '0' + (SettingTemp % 10); SettingTemp /= 10; } UART_Send_Data(UARTSendDataBuf, 21); //将数据发送到主机 #endif } #ifdef WATCHDOG IWDG_ReloadCounter(); //喂狗 #endif WakeCount++; WakeCount = WakeCount % WORK_TO_WAKE_RATIO; //每WORK_TO_WAKE_RATIO次唤醒采集一次传感器数据并上传(约WORK_TO_WAKE_RATIO*30秒采集上传一次) enableInterrupts(); AWU_Init(AWU_Timebase_30s); //30秒睡眠,注意!!实测睡眠时间误差较大 AWU_ReInitCounter(); AWU_Cmd(ENABLE); halt(); disableInterrupts(); }
//时间显示模式 u8 calendar_play(void) { u8 second=0; short temperate=0; //温度值 u8 t=0; u8 tempdate=0; u8 rval=0; //返回值 u8 res; u16 xoff=0; u16 yoff=0; //表盘y偏移量 u16 r=0; //表盘半径 u8 d=0; //指针长度 u8 TEMP_SEN_TYPE=0; //默认使用DS18B20 FIL* f_calendar=0; f_calendar=(FIL *)gui_memin_malloc(sizeof(FIL));//开辟FIL字节的内存区域 if(f_calendar==NULL)rval=1; //申请失败 else { res=f_open(f_calendar,(const TCHAR*)APP_ASCII_S6030,FA_READ);//打开文件 if(res==FR_OK) { asc2_s6030=(u8*)gui_memex_malloc(f_calendar->fsize); //为大字体开辟缓存地址 if(asc2_s6030==0)rval=1; else { res=f_read(f_calendar,asc2_s6030,f_calendar->fsize,(UINT*)&br); //一次读取整个文件 } f_close(f_calendar); } if(res)rval=res; } if(rval==0)//无错误 { LCD_Clear(BLACK);//清黑屏 second=calendar.sec;//得到此刻的秒钟 POINT_COLOR=GBLUE; Show_Str(48,60,lcddev.width,lcddev.height,(u8*)calendar_loading_str[gui_phy.language][0],16,0x01); //显示进入信息 if(DS18B20_Init()) { Show_Str(48,76,lcddev.width,lcddev.height,(u8*)calendar_loading_str[gui_phy.language][1],16,0x01); delay_ms(500); Show_Str(48,92,lcddev.width,lcddev.height,(u8*)calendar_loading_str[gui_phy.language][2],16,0x01); TEMP_SEN_TYPE=1; } delay_ms(1100);//等待1.1s BACK_COLOR= BLACK; LCD_Clear(BLACK);//清黑屏 if(lcddev.width==240) { r=80; d=7; }else if(lcddev.width==320) { r=120; d=9; }else if(lcddev.width==480) { r=160; d=12; } yoff=(lcddev.height-r*2-140)/2; TIME_TOPY=yoff+r*2+10; OTHER_TOPY=TIME_TOPY+60+10; xoff=(lcddev.width-240)/2; calendar_circle_clock_drawpanel(lcddev.width/2,yoff+r,r*2,d);//显示指针时钟表盘 calendar_date_refresh(); //加载日历 tempdate=calendar.w_date;//天数暂存器 gui_phy.back_color=BLACK; gui_show_ptchar(xoff+70-4,TIME_TOPY,lcddev.width,lcddev.height,0,GBLUE,60,':',0); //":" gui_show_ptchar(xoff+150-4,TIME_TOPY,lcddev.width,lcddev.height,0,GBLUE,60,':',0); //":" } while(rval==0) { RTC_Get(); //更新时间 if(system_task_return)break;//需要返回 if(second!=calendar.sec) //秒钟改变了 { second=calendar.sec; calendar_circle_clock_showtime(lcddev.width/2,yoff+r,r*2,d,calendar.hour,calendar.min,calendar.sec);//指针时钟显示时间 gui_phy.back_color=BLACK; gui_show_num(xoff+10,TIME_TOPY,2,GBLUE,60,calendar.hour,0X80); //显示时 gui_show_num(xoff+90,TIME_TOPY,2,GBLUE,60,calendar.min,0X80); //显示分 gui_show_num(xoff+170,TIME_TOPY,2,GBLUE,60,calendar.sec,0X80); //显示秒 if(t%2==0)//等待2秒钟 { if(TEMP_SEN_TYPE)temperate=Get_Temp();//得到内部温度传感器的温度值,0.1℃ else temperate=DS18B20_Get_Temp();//得到18b20温度 if(temperate<0)//温度为负数的时候,红色显示 { POINT_COLOR=RED; temperate=-temperate; //改为正温度 }else POINT_COLOR=BRRED; //正常为棕红色字体显示 gui_show_num(xoff+90,OTHER_TOPY,2,GBLUE,60,temperate/10,0X80); //XX gui_show_ptchar(xoff+150,OTHER_TOPY,lcddev.width,lcddev.height,0,GBLUE,60,'.',0); //"." gui_show_ptchar(xoff+180-15,OTHER_TOPY,lcddev.width,lcddev.height,0,GBLUE,60,temperate%10+'0',0);//显示小数 gui_show_ptchar(xoff+210-10,OTHER_TOPY,lcddev.width,lcddev.height,0,GBLUE,60,95+' ',0);//显示℃ if(t>0)t=0; } if(calendar.w_date!=tempdate) { calendar_date_refresh(); //天数变化了,更新日历. tempdate=calendar.w_date; //修改tempdate,防止重复进入 } t++; } delay_ms(20); }; while(tp_dev.sta&TP_PRES_DOWN)tp_dev.scan(0);//等待TP松开. gui_memex_free(asc2_s6030); //删除申请的内存 asc2_s6030=0; //清零 gui_memin_free(f_calendar); //删除申请的内存 POINT_COLOR=BLUE; BACK_COLOR=WHITE ; return rval; }
int main(void) { // u8 key; // u16 i=0; u16 adc_91000,adc_91200,reg_read_data=0,reg_write_data=0; float LMP91000_VOUT,LMP91200_VOUT,Temp_Integer,Temp_Decimal; short temp; u8 read_val[5] = {0xff}; u8 status = TI_LMP91000_NOT_READY; SystemInit(); delay_init(72); //延时初始化 NVIC_Configuration(); uart_init(9600); LED_Init(); KEY_Init(); Adc_Init(); IIC_Init(); //IIC初始化 LMP91200_Init(); //初始化PH delay_ms(500); printf("\nHello XXL"); /************************************************************ * 溶氧电极初始化及数据采集 ************************************************************/ LMP91000_ENABLE(); // enable LM while (status == TI_LMP91000_NOT_READY) // wait while device is not ready status = LMP91000_ReadOneByte(TI_LMP91000_STATUS_REG); // Read device ready status read_val[0] = LMP91000_ReadOneByte(TI_LMP91000_LOCK_REG); // Read from lock register default value 0x01 read_val[1] = LMP91000_ReadOneByte(TI_LMP91000_TIACN_REG); // Read TIA control register default value 0x03 read_val[2] = LMP91000_ReadOneByte(TI_LMP91000_REFCN_REG); // Read Reference control register default value 0x20 read_val[3] = LMP91000_ReadOneByte(TI_LMP91000_MODECN_REG); // Read Mode control register default value 0x00 LMP91000_WriteOneByte(TI_LMP91000_LOCK_REG, TI_LMP91000_WRITE_UNLOCK); // unlock the registers for write LMP91000_WriteOneByte(TI_LMP91000_TIACN_REG, TIACN_NEW_VALUE); // Modify TIA control register LMP91000_WriteOneByte(TI_LMP91000_REFCN_REG, REFCN_NEW_VALUE); // Modify REF control register LMP91000_WriteOneByte(TI_LMP91000_MODECN_REG, MODECN_NEW_VALUE); // Modify MODE control register read_val[1] = LMP91000_ReadOneByte(TI_LMP91000_TIACN_REG); // Read to confirm register is modified read_val[2] = LMP91000_ReadOneByte(TI_LMP91000_REFCN_REG); // Read to confirm register is modified read_val[3] = LMP91000_ReadOneByte(TI_LMP91000_MODECN_REG); // Read to confirm register is modified read_val[4] = LMP91000_ReadOneByte(TI_LMP91000_STATUS_REG); // test if write/read values match if (read_val[1] == TIACN_NEW_VALUE) { // while (1) // no error: blink LED continuously // { delay_ms(500); LED1=!LED1;//绿灯闪烁 // } } else { delay_ms(500); LED0=!LED0;//红灯闪烁 // error } // 获取LMP91000输出电压 // while(1) // { adc_91000=Get_Adc(ADC_Channel_8); LMP91000_VOUT=(float)adc_91000*(3.3/4096); LMP91000_VOUT=LMP91000_VOUT; printf("\n\nDO=%fv ",LMP91000_VOUT); temp=DS18B20_Get_Temp(); if(temp<0) { temp=-temp; } Temp_Integer=temp/10; Temp_Integer=Temp_Integer; //整数 Temp_Decimal=temp%10; Temp_Decimal=Temp_Decimal; //小数 printf(" Temp=%f.%fc " __TIME__ "",Temp_Integer,Temp_Decimal); delay_ms(1000); // } LMP91000_WriteOneByte(TI_LMP91000_LOCK_REG, TI_LMP91000_WRITE_LOCK); // lock the registers LMP91000_DISABLE(); /************************************************************ * PH电极初始化及数据采集,无论在空气,碱水,酸水中vout总是1.420~1.429,可能电极坏掉 ************************************************************/ Clr_LMP91200_CSN; reg_write_data = TI_LMP91200_CONFIG_REG_TEST_VALUE; // value to write reg_read_data = SPIx_ReadWriteByte(reg_write_data); // Write to config register, read old value reg_read_data = SPIx_ReadWriteByte(reg_write_data); // Write again to read previous update reg_read_data = SPIx_ReadWriteByte(reg_write_data); // Write again to read previous update,if not read this time,bit-15 will be wrong // Set_LMP91200_CSN; while(1) // test if write/read values match { if (reg_write_data == reg_read_data) { adc_91200=Get_Adc(ADC_Channel_9); LMP91200_VOUT=(float)adc_91200*(3.3/4096); LMP91200_VOUT=LMP91200_VOUT; LED1=!LED1; //正确则绿灯亮 delay_ms(500); } else { LED0=!LED0; //错误则黄灯亮 delay_ms(300); } } /************************************************************ * 温度传感器初始化及数据采集 ************************************************************/ while(DS18B20_Init())//初始化DS18B20,兼检测18B20 { delay_ms(600); // error_report();//DS18B20 未连接 } while(1) { temp=DS18B20_Get_Temp(); if(temp<0) { temp=-temp; } Temp_Integer=temp/10; Temp_Integer=Temp_Integer; //整数 Temp_Decimal=temp%10; Temp_Decimal=Temp_Decimal; //小数 delay_ms(500); LED1=!LED1;//DS1闪烁 } /************************************************************ * 按键扫描 ************************************************************/ #if 0 while(1) { key=KEY_Scan(); if(key==1)//KEY0按下,写入24C02 { ; } if(key==3)//KEY_UP按下,读取字符串并显示 { ; } i++; delay_ms(10); } #endif }
int main(void) { u16 times=0,i=0; NORMALTIME cur_time; //设置RTC的时间用 //Flash_Write(0x08041000,(u8 *)IndCalib,sizeof(IndCalib)); Flash_Read(0x08041000,(u8 *)IndCalib,sizeof(IndCalib)); delay_init(); //延时函数初始化 NVIC_Configuration(); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级 uart1_init(115200); //上位机通信模块 uart2_init(9600); //风速传感器模块 A2 A3 要转为232 //uart3_init(19200); //SD卡模块 (兼职风向-因为3有重映射功能) uart4_init(9600); //称重模块 uart5_init(9600); //AD模块 LED_Init(); //LED端口初始化 KEY_Init(); //初始化与按键连接的硬件接口 SD_init(); OPEN_SD_POWER; CLOSE_SD_POWER; OPEN_SD_POWER; CLOSE_SD_POWER; OPEN_SD_POWER; cur_time.tm_year = 2016; //2016-1900 cur_time.tm_mon = 5; cur_time.tm_mday = 29; cur_time.tm_hour = 23; cur_time.tm_min = 56; cur_time.tm_sec = 2; RTC_Init(cur_time);// while(DS18B20_Init())//初始化DS18B20,兼检测18B20 { printf("DS18B20 Check Failed!"); printf("Please Check! "); } printf("DS18B20 Ready! "); while(1) { if(IS_BUT_DN) { BEEP = 0; } else { BEEP = 1; g_PaOffset= -g_Pa; g_IndValOffset[0]= -Volt2Distance(0,g_IndVal[0]); g_IndValOffset[1]= -Volt2Distance(1,g_IndVal[1]); g_IndValOffset[2]= -Volt2Distance(2,g_IndVal[2]); g_IndValOffset[3]= -Volt2Distance(3,g_IndVal[3]); } if(times%60==0) { windSpeedDirFlag++; sendWindSpeedCmd(); //串口2 带232 //printf("3\r\n"); if(5 == windSpeedDirFlag) { windSpeedDirFlag = 0; } //printf("4\r\n"); //风速的反应慢 一秒钟最多发一次指令 不然传感器要疯掉 if(0 == windSpeedDirFlag) { uart3_init(19200); //SD卡模块 (兼职风向-因为3有重映射功能) g_uart3_used_for_SD = 1; // 日期 时间 位移1, 2, 3, 4 |拉力| 温度 |SD|风速|风向 sprintf(CmdStr,"#01,%02d-%02d-%02d,%02d:%02d:%02d,%04d,%04d,%04d,%04d,%04d,%04d,%04d,%04d,%04d,%04d,%1d,%04d,%04d!\r\n", cur_time.tm_year,cur_time.tm_mon,cur_time.tm_mday, cur_time.tm_hour,cur_time.tm_min,cur_time.tm_sec, dateSendtoPC[0],dateSendtoPC[1],dateSendtoPC[2],dateSendtoPC[3], dateSendtoPC[4], dateSendtoPC[6],dateSendtoPC[7],dateSendtoPC[8],dateSendtoPC[9], g_Temper,lastSDerr,g_WindSpeed,g_WindDir); //printf("7\r\n"); lastSDerr = write_string_to_files(CmdStr); } else { //printf("8\r\n"); uart3_init2(9600); //SD卡的usart3 重映射到 PB10 和PB11口 来读风向 g_uart3_used_for_SD = 0; send_byte_to_usart3(0x02);//初始化完后第一个字节会发不成功 sendWindDirCmd();//串口3 } //printf("11\r\n"); cur_time = Time_GetTime(); } if(times%10==0) { //sendWeightLoad1Cmd(); //称重标定代码 //printf("12\r\n"); switch(PC_Wcmd) { case 0x30: //printf("13\r\n"); BEEP = 1; sendWeightZeroCmd(); BEEP = 0; PC_Wcmd = 0; break; case 0x40: //printf("14\r\n"); BEEP = 1; sendWeightLoad1Cmd(); PC_Wcmd = 0; BEEP = 0; break; case 0x41: //printf("15\r\n"); BEEP = 1; sendWeightLoad2Cmd(g_weightCalib[0],g_weightCalib[1]); PC_Wcmd = 0; BEEP = 0; break; default: //printf("16\r\n"); //sendWeightLoad2Cmd(0x27,0x10); sendWeightCmd(); //串口4 break; } BLED3=1; sendADCmd(); //串口5 BLED3=0; dateSendtoPC[0] = g_IndVal[0]; dateSendtoPC[1] = g_IndVal[1]; dateSendtoPC[2] = g_IndVal[2]; dateSendtoPC[3] = g_IndVal[3]; dateSendtoPC[4] = g_PaOffset + g_Pa; dateSendtoPC[6] = g_IndValOffset[0] + Volt2Distance(0,g_IndVal[0]); dateSendtoPC[7] = g_IndValOffset[1] + Volt2Distance(1,g_IndVal[1]); dateSendtoPC[8] = g_IndValOffset[2] + Volt2Distance(2,g_IndVal[2]); dateSendtoPC[9] = g_IndValOffset[3] + Volt2Distance(3,g_IndVal[3]); } switch(PC_cmd) { case 1: BLED2 = 1; // 日期 时间 位移1, 2, 3, 4 |拉力| 温度 |SD|风速|风向 sprintf(CmdStr,"#01,%02d-%02d-%02d,%02d:%02d:%02d,%04d,%04d,%04d,%04d,%04d,%04d,%04d,%04d,%04d,%04d,%d,%04d,%04d!\r\n", cur_time.tm_year,cur_time.tm_mon,cur_time.tm_mday, cur_time.tm_hour,cur_time.tm_min,cur_time.tm_sec, dateSendtoPC[0],dateSendtoPC[1],dateSendtoPC[2],dateSendtoPC[3], dateSendtoPC[4], dateSendtoPC[6],dateSendtoPC[7],dateSendtoPC[8],dateSendtoPC[9], g_Temper,lastSDerr,g_WindSpeed,g_WindDir); send_string_to_usart1(CmdStr); BLED2 = 0; PC_cmd = 0; break; case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: BEEP = 1; sprintf(CmdStr,"#%02x",PC_cmd); for(i=0;i<21;i++) { sprintf(CmdStr,"%s,%+05d",CmdStr,IndCalib[PC_cmd-0x10][i]); } sprintf(CmdStr,"%s!\r\n",CmdStr); send_string_to_usart1(CmdStr); PC_cmd = 0; BEEP = 0; break; case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: sprintf(CmdStr,"#%02x",PC_cmd-0x10); for(i=0;i<21;i++) { sprintf(CmdStr,"%s,%+05d",CmdStr,IndCalib[PC_cmd-0x20][i]); } sprintf(CmdStr,"%s!\r\n",CmdStr); send_string_to_usart1(CmdStr); PC_cmd = 0; break; } times++; delay_ms(10); } }