使用最新版STM32G431系列,cubemx配置
1 题目分析
使用到的外设:LED、LCD、按键、串口、ADC、E2PROM、RTC。
2 Cubemx配置
外设具体方法参考我写的其他文章
配置完成如下:
时钟树配置如下:
3 文件移植
其中灯和按键程序自己添加
添加到项目中
先编译,左边会显示出添加的文件
添加头文后再编译一下,确保头文件和.c文件都被正确引用
4 代码
所有的外设配置Cubemx都配置好了,无需自己配置(巨省工作量)
下面介绍自己添加的部分
4.1 led和Key部分
头文件 ledAndKey.h
#include "main.h"
void Led_Disp(unsigned char c);
unsigned char Key_Scan(void);
.c文件
#include "ledAndKey.h"
//灯
void Led_Disp(unsigned char c)
{
//全部熄灭
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_8
|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
//点亮对应位
HAL_GPIO_WritePin(GPIOC, c<<8, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
}
//按键扫描
unsigned char Key_Scan(void)
{
unsigned char c;
if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)==GPIO_PIN_RESET)
{
c = 1;
}
else if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1)==GPIO_PIN_RESET)
{
c = 2;
}
else if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2)==GPIO_PIN_RESET)
{
c = 3;
}
else if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)==GPIO_PIN_RESET)
{
c = 4;
}
return c;
}
4.2 ADC部分
ADC文件最后添加两个函数
int GetADC1_R38(void);
int GetADC2_R37(void);
int GetADC1_R38(void)
{
int a;
HAL_ADC_Start(&hadc2);
a = HAL_ADC_GetValue(&hadc2);
return a;
}
int GetADC2_R37(void)
{
int a;
HAL_ADC_Start(&hadc1);
a = HAL_ADC_GetValue(&hadc1);
return a;
}
4.3 i2c部分
添加读和写两个函数
void i2cWrite(unsigned char *p,unsigned char addr,unsigned char num);
void i2cRead(unsigned char *p,unsigned char addr,unsigned char num);
void i2cWrite(unsigned char *p,unsigned char addr,unsigned char num)
{
I2CStart();
I2CSendByte(0xa0);
I2CWaitAck();
I2CSendByte(addr);
I2CWaitAck();
while(num--)
{
I2CSendByte(*p++);
I2CWaitAck();
}
I2CStop();
delay1(500);
}
void i2cRead(unsigned char *p,unsigned char addr,unsigned char num)
{
I2CStart();
I2CSendByte(0xa0);
I2CWaitAck();
I2CSendByte(addr);
I2CWaitAck();
I2CStart();
I2CSendByte(0xa1);
I2CWaitAck();
while(num--)
{
*p++ = I2CReceiveByte();
if(num)
I2CSendAck();
else
I2CSendNotAck();
}
I2CStop();
}
4.4 主函数部分
#include "main.h"
#include "adc.h"
#include "rtc.h"
#include "usart.h"
#include "gpio.h"
#include "ledAndKey.h"
#include <stdio.h>
#include "i2c - hal.h"
#include "lcd.h"
void SystemClock_Config(void);
void keyPro(void);
void lcdPro(void);
void ledPro(void);
void ADCPro(void);
//dida
__IO uint32_t uwtick_Key,uwtick_Lcd,uwtick_Led,uwtick_ADC,uwtick_rx_it;
//key
unsigned char Key_Value,Key_Old,Key_Up,Key_Dowm;
//adc
double ADCR37,ADCR38;
//led
unsigned char LED_Value;
//user
unsigned char page = 1;
unsigned char str[20];
unsigned char uart_rx_it[1];
unsigned char uart_rx[5];
char uart_tx[20];
unsigned char k = 1;
unsigned char LED_FLAG = 1;//默认开
unsigned char Display_num = 0;
unsigned char SET_TIM_FLAG;
unsigned char RX_FLAG = 0;//有效数据标志位
unsigned char TX_FLAG = 0;//发送标志位 避免多次发送
RTC_DateTypeDef rtc_date;
RTC_TimeTypeDef rtc_time;
RTC_TimeTypeDef set_time;
RTC_TimeTypeDef set_time_change;
int main(void)
{
HAL_Init();
SystemClock_Config();
LCD_Init();
I2CInit();
MX_GPIO_Init();
MX_ADC1_Init();
MX_ADC2_Init();
MX_RTC_Init();
MX_USART1_UART_Init();
HAL_UART_Receive_IT(&huart1,uart_rx_it,1);
LCD_Clear(Blue);
LCD_SetBackColor(Blue);
LCD_SetTextColor(White);
set_time.Hours = 0;
set_time.Minutes = 0;
set_time.Seconds = 0;
// i2cWrite(&k,0,1);
//读取i2c中k值
HAL_Delay(10);
i2cRead(&k,0,1);
while (1)
{
ADCPro();
keyPro();
lcdPro();
ledPro();
}
}
void lcdPro(void)
{
if(uwTick - uwtick_Lcd<50) return;
uwtick_Lcd = uwTick;
//时间处理
HAL_RTC_GetDate(&hrtc,&rtc_date,FORMAT_BIN);
HAL_RTC_GetTime(&hrtc,&rtc_time,FORMAT_BIN);
//判断定时时间
if(rtc_time.Hours==set_time.Hours&&rtc_time.Minutes == set_time.Minutes&&rtc_time.Seconds == set_time.Seconds)
{
if(TX_FLAG == 0)
{
sprintf(uart_tx,"%4.2f+%3.1f+%02d%02d%02d\n",ADCR38,k*0.1,rtc_time.Hours,rtc_time.Minutes,rtc_time.Seconds);
HAL_UART_Transmit(&huart1,(unsigned char *)uart_tx,strlen(uart_tx),50);
TX_FLAG = 1;
}
}
else
{
TX_FLAG = 0;
}
if(page == 1)
{
sprintf((char *)str,"V1:%4.2fV",ADCR38);
LCD_DisplayStringLine(Line0,str);
sprintf((char *)str,"k:%3.1f",k*0.1);
LCD_DisplayStringLine(Line1,str);
if(LED_FLAG == 0)
{
sprintf((char *)str,"LED:OFF ");
}
else
{
sprintf((char *)str,"LED:ON ");
}
LCD_DisplayStringLine(Line2,str);
sprintf((char *)str,"T:%02d-%02d-%02d",rtc_time.Hours,rtc_time.Minutes,rtc_time.Seconds);
LCD_DisplayStringLine(Line3,str);
}
else
{
sprintf((char *)str,"Setting");
LCD_DisplayStringLine(Line1,str);
if(Display_num == 0)
{
sprintf((char *)str,"T:%02d-%02d-%02d",set_time.Hours,set_time.Minutes,set_time.Seconds);
}
else //设置状态闪烁
{
if(SET_TIM_FLAG<4)//200ms
{
if(Display_num == 1)
sprintf((char *)str,"T: -%02d-%02d",set_time_change.Minutes,set_time_change.Seconds);
else if(Display_num == 2)
sprintf((char *)str,"T:%02d- -%02d",set_time_change.Hours,set_time_change.Seconds);
else if(Display_num == 3)
sprintf((char *)str,"T:%02d-%02d- ",set_time_change.Hours,set_time_change.Minutes);
}
else
{
sprintf((char *)str,"T:%02d-%02d-%02d",set_time_change.Hours,set_time_change.Minutes,set_time_change.Seconds);
}
SET_TIM_FLAG ++;
if(SET_TIM_FLAG > 7)
{
SET_TIM_FLAG = 0;
}
}
LCD_DisplayStringLine(Line3,str);
}
}
void keyPro(void)
{
if(uwTick - uwtick_Key<50) return;
uwtick_Key = uwTick;
Key_Value = Key_Scan();
Key_Dowm = Key_Value&(Key_Value^Key_Old);
Key_Up = ~Key_Value&(Key_Value^Key_Old);
Key_Old = Key_Value;
if(Key_Dowm == 1)
{
if(LED_FLAG == 0)
LED_FLAG = 1;
else
LED_FLAG = 0;
}
else if(Key_Dowm == 2)
{
LCD_Clear(Blue);
if(page == 1)
{
page = 2;
set_time_change = set_time; //
}
else //更新数值
{
page = 1;
set_time = set_time_change;
}
}
else if(Key_Dowm == 3)
{
if(Display_num == 0)
Display_num = 1;
else if(Display_num == 1)
Display_num = 2;
else if(Display_num == 2)
Display_num = 3;
else
Display_num = 1;
}
else if(Key_Dowm == 4)
{
if(page == 2)
{
if(Display_num == 1)
{
set_time_change.Hours++;
if(set_time_change.Hours == 60)
set_time_change.Hours = 0;
}
else if(Display_num == 2)
{
set_time_change.Minutes++;
if(set_time_change.Minutes == 60)
set_time_change.Minutes = 0;
}
else if(Display_num == 3)
{
set_time_change.Seconds++;
if(set_time_change.Seconds == 60)
set_time_change.Seconds = 0;
}
}
}
}
void ledPro(void)
{
if(uwTick - uwtick_Led<200) return;
uwtick_Led = uwTick;
if(ADCR38>3.3*k*0.1)
{
LED_Value^=0x1;
}
else
{
LED_Value= 0;
}
if(LED_FLAG)
{
Led_Disp(LED_Value);
}
}
void ADCPro(void)
{
if(uwTick - uwtick_ADC<50) return;
uwtick_ADC = uwTick;
ADCR38 = GetADC1_R38()*3.3/4096;
ADCR37 = GetADC2_R37()*3.3/4096;
}
//接受中断 状态机控制接受流程
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(uart_rx_it[0] == 'k'&&RX_FLAG == 0) //有效
{
RX_FLAG = 1;
uwtick_rx_it = uwTick; //开始计时
}
else if(RX_FLAG == 1) //0
{
if(uart_rx_it[0]=='0')
{
uart_rx[0] = uart_rx_it[0];
RX_FLAG++;
}
else //数据无效
{
RX_FLAG = 0;
}
}
else if(RX_FLAG == 2) //.
{
if(uart_rx_it[0]=='.')
{
uart_rx[1] = uart_rx_it[0];
RX_FLAG++;
}
else //数据无效
{
RX_FLAG = 0;
}
}
else if(RX_FLAG == 3) //k
{
if(uart_rx_it[0]>='0'&&uart_rx_it[0]<='9')//接受成功
{
uart_rx[2] = uart_rx_it[0];
RX_FLAG = 0;
//更新k值,并保存
k = uart_rx[2] - 0x30;
i2cWrite(&k,0,1);
//返回ok
sprintf(uart_tx,"ok\n");
HAL_UART_Transmit(&huart1,(unsigned char *)uart_tx,strlen(uart_tx),50);
}
else
{
RX_FLAG = 0;
}
}
// else if(RX_FLAG == 4) //\n
// {
// if(uart_rx_it[0] == 10) //接受成功
// {
// uart_rx[3] = uart_rx_it[0];
// RX_FLAG = 0;
// //更新k值,并保存
// k = uart_rx[2] - '0';
// i2cWrite(&k,0,1);
// //返回ok
// sprintf(uart_tx,"ok\n");
// HAL_UART_Transmit(&huart1,(unsigned char *)uart_tx,strlen(uart_tx),50);
// }
// else
// {
// RX_FLAG = 0;
// }
// }
if(uwTick-uwtick_rx_it>200)//超时
{
RX_FLAG = 0;
}
HAL_UART_Receive_IT(&huart1,uart_rx_it,1);
}