8.注意打对:0x00 而不是 ox00
9.注意打对:sprintf((char*)display_buf," X:%.1f ",price_x/10.0f);//作为浮点数返回,并显示1位小数 不是%1.f
10.液晶屏上显示有误:1.逻辑函数错误 2.显示printf处或许有格式错误
11.每次写if 都要想想是否有else
3.读写EEPROM
1)加入i2c.c(原名为i2c_hal.c/h),改名,注意.c中的include也要改
2)启用新模块,必须记得启动初始化 Init();(在其.c文件中调用)
3)再i2c.c中编写 读写EEPROM函数,写完后记得在i2c.h中声明
void EEPROM_Write(u8 add,u8 dat)//写函数:先找到外设地址,再确定寄存器地址,最后才写入数据
{
I2CStart();
//启动I2C后进行第一次发送:先找到器件地址,并确定读或写
I2CSendByte(0xa0);//a为器件地址,0为单片机向此外设写数据
I2CWaitAck();//等待外设发送应答信号
//第二次发送:确定向从器件的寄存器的哪个地址发送数据,此次发送为地址
I2CSendByte(add); //发送从器件的地址
I2CWaitAck(); //等待从器件应答
//第三次发送:向从器件的确定地址写入数据,此次发送为数据写入
I2CSendByte(dat); //向从器件写入数据
I2CWaitAck(); //等待从器件应答
I2CStop();//关闭I2C
HAL_Delay(5);//延时5ms,因为EEPROM的每次数据写入和擦除需间隔时间
}
//读24C02
u8 EEPROM_Read(u8 add)//读函数:找到外设寄存器地址,读取其值,再赋值给单片机的dat变量
{
u8 dat;
I2CStart(); //启动I2C
I2CSendByte(0xa0);//找到器件地址,0为向外设写数据
I2CWaitAck();
I2CSendByte(add);//写入需找的外设寄存器地址
I2CWaitAck();
I2CStart();//注意,读函数需重新启动一次I2C
I2CSendByte(0xa1); //找到器件地址,1为从外设读取数据至单片机
I2CWaitAck();
dat = I2CReceiveByte(); //把读到的数据赋值给单片机,此时为外设向SDA线写入数据
I2CSendNotAck();//单片机发送NACK信号,表明主机已接受到需求数据,发出信号以表停止通信
I2CStop();//释放总线
return(dat);//注意最后需将读取的信号返回给单片机,方便调用
}
4)编写I2C初始化Read函数,此函数放main的初始化内
//EEPROM读取初始化
void EEPROM_Init_Read()
{
//判断是否为第一次开机
if(EEPROM_Read(0Xf0) !=0xaa)//第一次开机,任意地址初始值为0Xff,此即为第一次开机
{
EEPROM_Write(0xf0,0xaa);//若为第一次开机,则作标志,表明下一次开机不为第一次
//第一次开机,要初始化写入原有数据
EEPROM_Write(0x00,rep_x);
EEPROM_Write(0x01,rep_y);
EEPROM_Write(0x02,price_x);
EEPROM_Write(0x03,price_y);
}
//不为第一次开机,则读取上次数据
rep_x = EEPROM_Read(0x00);
rep_y = EEPROM_Read(0x01);
price_x = EEPROM_Read(0x02);
price_y = EEPROM_Read(0x03);
}
5)根据实际需求在其他函数内调用EEPROM_Read(); EEPROM_Write();
4.led控制
1)手动编写led.c、led.h
2)设定led控制变量,可用于其他函数调用控制
3)编写LED_Process(); 运用于while(1)中,内调用led.control函数
4)设定LED状态标志变量 :bool ld1_flag = 0; 注意,bool类型需要#include <stdbool.h>
布尔类型,用于表示真(true)或假(false)的值。布尔类型在C++中用于存储逻辑值,通常用于条件判断和控制流程。
问题:SysTick中断 硬件端口共用 HAL_IncTick作用 LED_Control放while里 其余放SysTick中断里?
原因:LED_Process放SysTick中断函数内会影响LCD显示,因为共用同一IO口(PC)
解决:将LED_Control()放入while里面,LED_Process放SysTick中断函数里面
why:SysTick_Handler(void)是每1ms执行一次的中断函数,所以把LED_Process放进去,方便计数 并作出对控制变量led_ctr的反应。将LED_Control()放入while里面,方便及时捕捉led_ctr的变化,点亮led。
细节知识点:
1)SysTick_Handler(void)是一个系统滴答时钟中断函数。它是在SysTick定时器溢出时自动调用的函数。在这个函数中,可以执行一些任务或者调用其他函数来处理定时器中断事件。
2)滴答定时器的中断函数一般在it的.c文件中,可以移到main.c中来更好处理
3)HAL_IncTick()是一个函数,用于增加系统滴答定时器的计数器值。在SysTick()函数中必出现。
4)对于SysTick_Handler(void)的重定义问题,打开g4_it.c,注释掉原有的SysTick_Handler(void),在main中重新写一个
5.PWM输出
1)根据外设初始化 HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2);//看原定外设
2)编写PWM_Process(),用于状态变化时,直接操作寄存器更改占空比或频率
3)放入while(1)中
知识点:直接操作TIM寄存器更改其占空比和频率?
6.USART
1.串口打印重定向函数int fputc(int ch,FILE*F)比较重要,或许引起乱码问题:
1)在usart.c中定义,记得调用"stdio.h"函数(FILE需要)
2)写对,之后可在main函数直接用printf串口打印
2.在main中编写串口接收函数,注意设定接收数组buf[2],一位数据位,一位停止位,注意结束符3.在初始化处开启串口接收中断 HAL_UART_Receive_IT(&huart1,uart_buf,1);
4.\r\n可放printf后,换行(\换行 /除)