#注意点总结
1,针对系统的代码,子函数按功能划分:实时数据刷新函数(接收电压值和接收方波信号),LCD页面显示函数(设置界面和实时数据显示界面),Key操作函数,E2写入和读取函数,LED报警函数,串口操作函数,数据储存函数;
2,注意,u16和u8的使用,u8的数据最大支持(256-1),u16最大支持(65536-1)
3,E2写入和读取时需注意:写入的为u8类型数据,若为其他类型,需强制转换,但要保证数据大小读取和写入前后不变,可以和放大或缩小数据一起使用。
4,解决LCD两个页面的冲突问题:当个高亮设置界面最后一行时,设置界面第一行会高亮,并且此时回到实时数据显示界面,也会高亮,应该分别在两页面的第一行写上代码字体颜色。
5,解决RTC计时会先出现24:00:00,后又出现00:00:00,造成重复,可以在RTC中断函数里设置
if(time == 24 * 3600)
{
RTC_SetCounter(1);//避免出现一次24:00:00后,又出现一次00:00:00
}
// if(time==23*3600+59*60+59)//这种写法可以出现00:00:00
// {
// RTC_SetCounter(0);
// }
6,之前自己习惯使用滴答定时器来进行设标志位(没有功能划分思想,原意是按部件拆分思想,发现部件独立,无法串联),在主函数中读取标志位进行操作,出现的问题是造成程序堵塞,后改为定时器定时,程序稳定(也是有功能划分的功劳),滴答定时器只用于简单的1ms计时。
7,学习了LED的寄存器操作方法:简单,易懂
(1)在LED初始化中首先需要对灯全灭:
GPIOC->ODR|=0XFF00;
GPIOD->ODR|=(1<<2);
GPIOD->ODR&=~(1<<2);
(2)设置LED变量
u32 LED_MODE=0XFFFF;
(3)闪烁,点亮,熄灭LED1
LED_MODE^=(1<<8);//闪烁
LED_MODE&=~(1<<8);//点亮
LED_MODE|=(1<<8);//熄灭
GPIOC->ODR=LED_MODE;
GPIOD->ODR|=(1<<2);
GPIOD->ODR&=~(1<<2);
8,关于PWM捕捉,使用的是系统自带的通道一和通道二捕捉(直连和非直连),优点是中断函数简单容易理解,缺点是只能捕捉一路。
<捕捉讲解>
9.按数据采样间隔采集数据:定时器中根据 采样间隔 设置 采集标志位 置一
#黏贴代码
##main.c
#include"stm32f10x.h"
#include"led.h"
#include"key.h"
#include"timer.h"
#include"adc.h"
#include"pwm.h"
#include"i2c.h"
#include"e2prom.h"
#include"lcd.h"
#include"stdio.h"
#include"rtc.h"
#include"capture.h"
#include"usart2.h"
//变量声明区//
u32 delaytime;
u32 LED_MODE=0XFFFF;
extern u8 flag200ms;
u8 string[20];
//界面显示//
u8 SetFlag=0;//界面切换
u8 ChooseFlag=1;//高亮切换
//实时显示//
float AdcVal;//接收电压值
float TH;//转化成的温度
float Fre=1.0;//信号发出频率
float RH;//转化成的湿度
extern u32 Frequence;
u32 time=0;
u8 HH=0;
u8 MM=0;
u8 SS=0;
//参数设置//
int TH_Limit=40;//温度上限,有正负
u8 RH_Limit=80;//湿度上限
u8 SampleTime=1;//采样间隔
//测试信号:Fre
//缓冲区//
int TH_LimitBuf=40;
u8 RH_LimitBuf=80;
u8 SampleTimeBuf=1;
float FreBuf;
//串口//
u8 RxdCnt=0;
u8 RxdOver=0;
u8 RxdBuf[20];
float TH_Buf;//实时温度储存在数组里的变量
float RH_Buf;//实时湿度储存在数组里的变量
u32 HH_Buf;//小时储存在数组里的变量
u32 MM_Buf;//分钟储存在数组里的变量
u32 SS_Buf;//毫秒储存在数组里的变量
//采样相关变量
int Record[70][5];
u16 RecordCnt = 0;
extern u8 RecordFlag ;
//函数声明区//
void delay_ms(u32 times);
void KeyAction(int code);
void RefreshData(void);
void WriteE2Data(void);
void ReadE2Data(void);
void ShowReal(void);
void ShowSet(void);
void UsartAction(void);
void RecordAction(void);
void LED_Thr(void);
int main()
{
SysTick_Config(SystemCoreClock/1000);
STM3210B_LCD_Init();
RTC_Init(23,59,55);
USART2_Init();
Capture_Init();
LED_Init();
Key_Init();
ADC1_Init();
i2c_init();
TIM4_Init(2000,72);//2ms定时器
LCD_Clear(Blue);
LCD_SetBackColor(Blue);
LCD_SetTextColor(White);
ReadE2Data();
TH_Limit=TH_LimitBuf;
RH_Limit=RH_LimitBuf;
SampleTime=SampleTimeBuf;
Fre=FreBuf;
PWM_Init(Fre*1000,50);
while(1)
{
KeyDriver();
if(flag200ms==1)
{
RefreshData();
if(SetFlag==1)
{
ShowSet();
}
else
{
ShowReal();
}
flag200ms=0;
LED_Thr();//实时值与阈值比较,注意不要让设置值即时生效,和Buf比较
}
if(RxdOver)
{
UsartAction();
RxdOver=0;
}
if(RecordFlag)
{
RecordAction();
RecordFlag=0;
}
}
}
void LED_Thr(void)
{
if(TH>TH_LimitBuf)
{
LED_MODE^=(1<<8);
}
else
{
LED_MODE|=(1<<8);
}
if(RH>RH_LimitBuf)
{
LED_MODE^=(1<<9);
}
else
{
LED_MODE|=(1<<9);
}
GPIOC->ODR=LED_MODE;
GPIOD->ODR|=(1<<2);
GPIOD->ODR&=~(1<<2);
}
void RecordAction(void)
{
Record[RecordCnt][0]=TH;//实时温度
Record[RecordCnt][1]=RH;
Record[RecordCnt][2]=HH;
Record[RecordCnt][3]=MM;
Record[RecordCnt][4]=SS;
RecordCnt++;
if(RecordCnt>60)
{
RecordCnt=0;
}
LED_MODE^=(1<<10);
GPIOC->ODR=LED_MODE;
GPIOD->ODR|=(1<<2);
GPIOD->ODR&=~(1<<2);
}
void UsartAction(void)
{
u8 i=0;
u8 usart_str[50];
if(RxdBuf[0]=='C')
{
HH_Buf=Record[RecordCnt-1][2];
MM_Buf=Record[RecordCnt-1][3];
SS_Buf=Record[RecordCnt-1][4];
sprintf((char*)usart_str,"TH_Limit:%dC,RH_Limit:%d%%,TIME:%.2d:%.2d:%.2d\r\n",TH_Limit,RH_Limit,HH_Buf,MM_Buf,SS_Buf);
USART2_SendString(usart_str);
}
else if(RxdBuf[0]=='T')
{
for(i=0;i<RecordCnt;i++)
{
TH_Buf=Record[i][0];
RH_Buf=Record[i][1];
HH_Buf=Record[i][2];
MM_Buf=Record[i][3];
SS_Buf=Record[i][4];
sprintf((char*)usart_str,"TH:%.0fC RH:%.0f%% TIME:%.2d:%.2d:%.2d\r\n",TH_Buf,RH_Buf,HH_Buf,MM_Buf,SS_Buf);
USART2_SendString(usart_str);
}
}
//别忘了这两个
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//接收的数据处理完毕后打开接收中断
for(i=0; i<20; i++)//清空缓冲区
RxdBuf[i] = 0;
}
void ShowReal(void)
{
LCD_SetTextColor(White);//注意这里加上是最后一行高亮,实时数据显示不高亮
LCD_DisplayStringLine(Line1,(u8*)" Real Data ");//左5
sprintf((char*)string," TH : %.0fC ",TH);
LCD_DisplayStringLine(Line3,string);
sprintf((char*)string," RH : %.0f%% ",RH);//注意百分号的书写方式
LCD_DisplayStringLine(Line5,string);
sprintf((char*)string," TIME : %.2d:%.2d:%.2d ",HH,MM,SS);
LCD_DisplayStringLine(Line7,string);
sprintf((char*)string," RecordCnt : %d ",RecordCnt);
LCD_DisplayStringLine(Line9,string);
}
void ShowSet(void)
{
LCD_SetTextColor(White);//注意这里加上是最后一行高亮,第一行不高亮
LCD_DisplayStringLine(Line1,(u8*)" Set Data ");//左5
if(ChooseFlag==1)
{
LCD_SetTextColor(Green);
}
else
{
LCD_SetTextColor(White);
}
sprintf((char*)string," TH_Limit : %dC ",TH_Limit);
LCD_DisplayStringLine(Line3,string);
if(ChooseFlag==2)
{
LCD_SetTextColor(Green);
}
else
{
LCD_SetTextColor(White);
}
sprintf((char*)string," RH_Limit : %d%% ",RH_Limit);
LCD_DisplayStringLine(Line5,string);
if(ChooseFlag==3)
{
LCD_SetTextColor(Green);
}
else
{
LCD_SetTextColor(White);
}
sprintf((char*)string," SampleTime : %ds ",SampleTime);
LCD_DisplayStringLine(Line7,string);
if(ChooseFlag==4)
{
LCD_SetTextColor(Green);
}
else
{
LCD_SetTextColor(White);
}
sprintf((char*)string," TestFre : %.1fKhz ",Fre);
LCD_DisplayStringLine(Line9,string);
}
void WriteE2Data(void)
{
if(TH_LimitBuf<0)
{
E2Write(0x00,1);
delay_ms(5);
E2Write(0x01,(u8)(-TH_LimitBuf));//注意E2中储存的是u8类型;
}
else
{
E2Write(0x00,0);
delay_ms(5);
E2Write(0x01,(u8)TH_LimitBuf);
}
delay_ms(5);
E2Write(0x02,RH_LimitBuf);
delay_ms(5);
E2Write(0x03,SampleTimeBuf);
delay_ms(5);
E2Write(0x04,(u8)(FreBuf*10)); //注意转换数据类型的同时保持数值不变
delay_ms(5);
}
void ReadE2Data(void)
{
// u8 i;
// i=E2Read(0x00);
// delay_ms(5);
// if(i==1)
// {
// TH_LimitBuf=-E2Read(0x01);
// delay_ms(5);
// }
// else
// {
// TH_LimitBuf=E2Read(0x01);
// delay_ms(5);
// }
TH_LimitBuf = E2Read(0x01);
delay_ms(5);
if(E2Read(0x00))
{
delay_ms(5);
TH_LimitBuf = -TH_LimitBuf;
}
RH_LimitBuf=E2Read(0x02);
delay_ms(5);
SampleTimeBuf=E2Read(0x03);
delay_ms(5);
FreBuf=(float)E2Read(0x04)/10;
delay_ms(5);
}
void RefreshData(void)
{
AdcVal=Get_ADC()*3.3/4096;
TH=AdcVal*80/3.3-20;
RH=(Frequence/1000*80+10)/9;//注意考虑百分数的整数部分
}
void delay_ms(u32 times)
{
delaytime=times;
while(delaytime!=0);
}
void KeyAction(int code)
{
if(code==1)
{
if(SetFlag==1)
{
SetFlag=0;
}
else if(SetFlag==0)
{
TH_LimitBuf=TH_Limit;
RH_LimitBuf=RH_Limit;
SampleTimeBuf=SampleTime;
FreBuf=Fre;
PWM_Init(FreBuf*1000,50);
WriteE2Data();
SetFlag=1;
}
LCD_Clear(Blue);//清楚界面,防止有乱码产生
}
else if(code==2)
{
if(SetFlag==1)
{
ChooseFlag++;
if(ChooseFlag>4)
{
ChooseFlag=1;
}
}
}
else if(code==3)
{
if(SetFlag==1)
{
switch(ChooseFlag)
{
case 1: TH_Limit++;
if(TH_Limit>60) TH_Limit=60;
break;
case 2: RH_Limit+=5;
if(RH_Limit>90) RH_Limit=90;
break;
case 3: SampleTime++;
if(SampleTime>5) SampleTime=5;
break;
case 4: Fre+=0.5;
if(Fre>10) Fre=10;
break;
}
}
}
else if(code==4)
{
if(SetFlag==1)
{
switch(ChooseFlag)
{
case 1: TH_Limit--;
if(TH_Limit<-20) TH_Limit=-20;
break;
case 2: RH_Limit-=5;
if(RH_Limit<10) RH_Limit=10;
break;
case 3: SampleTime--;
if(SampleTime<1) SampleTime=1;
break;
case 4: Fre-=0.5;
if(Fre<1) Fre=1;
break;
}
}
}
}