LED的程序设计
8个LED在该嵌入式板子上分别与PC8-PC15相连,因为LED一段连接着VCC,高电平,所以低电平LED亮,高电平LED灭,LED的另一端连接着锁存器,而锁存器在高电平时不锁存数据,在低电平时候锁存数据,即低电平时输出不随输入变化,即使是PC8-PC15的电平发生变化,LED也不随之变化。因此我们可以既控制锁存器来对LED的状态进行控制,也可以调用这些引脚上的资源。
根据STMCubeMX进行配置
1.对时钟进行配置
将时钟配置成80MHz,我们在STMCubeMx上配置如下系数:
2.RCC配置
使用的是外部晶振,所以在配置中应该将模式配置成外部晶振模式。
3.SYS配置
将配置调制成SW下载模式。
4.引脚配置
将PC8-PC15初始配置为低电平,然后将PD2初始配置为低电平,都为开漏输出,如下图:
5.文件输出
在PROJECT MANGER中将编辑器改成MDK,新竞赛板子必须用KEIL V5以上的版本,文件路径不能有中文,否则起始的处理.s文件无法添加,起始会报错 在code generator中勾选一下选项
代码处理
1.led初始化
将 gpio.c中的MX_GPIO_Init(void)改写为LED_Init(void),这能方便后续程序的改下,和模块化的操作能更加方便。
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOF_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
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_RESET);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
GPIO_InitStruct.Pin = 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_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
}
2.LED处理函数(显示)
void LED_Disp(unsigned char ucLed)
{
HAL_GPIO_WritePin(GPIOC,ucLed<<8,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOD,GPIO_Pin_2,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD,GPIO_Pin_2,GPIO_PIN_RESET);
}
独立按键的程序设计
4个独立摁键分别对应着引脚上的PB0(k1),PB1(k2),PB2(k3),PA0(k4),这四个独立摁键的另一端连接着地,当没摁下的时候,因为vcc的接入,所以引脚检测到的是高电平,当摁下时,摁键相当于短路,所以引脚直接接入地,检测电压为低电平。
1.cubemx配置信息
将gpio先配置成上拉模式(pull up)即上电为高电平,此时配置,其他的基本配置都相同时,应该如下图:
代码处理
1.KEY初始化
将 gpio.c中的MX_GPIO_Init(void)改写为KEY_Init(void),这能方便后续程序的改下,和模块化的操作能更加方便。
void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOF_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
2.KEY处理
有消抖操作
unsigned char KEY_Scan(void)
{
unsigned char ucKey_Val=0;
if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)==0)
{
HAL_Delay(10);
if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)==0)
{
ucKey_Val=1;
}
}
if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1)==0)
{
HAL_Delay(10);
if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1)==0)
{
ucKey_Val=2;
}
}
if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2)==0)
{
HAL_Delay(10);
if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1)==0)
{
ucKey_Val=3;
}
}
if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)==0)
{
HAL_Delay(10);
if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1)==0)
{
ucKey_Val=4;
}
}
return ucKey_Val;
}
void KEY_Proc(void)
{
unsigned char ucKey_Val;
ucKey_Val=KEY_Scan();
if(ucKey_Val!=ucKey_Long)
{
ucKey_Long=ucKey_Val;
ucKey_Time=ucTick_ms;
}
else
ucKey_Val=0;
if(ucKey_Val==1)
{
}
if(ucKey_Long==1)
{
if(ucTick_ms-ucKey_Time>800)
{
ucKey_Time=ucTick_ms;
}
}
}
LCD应用程序设计
根据比赛时会给lcd…c和font.c还有.h文件添加到我们的工程里,并且进行调用,先在keil图标中 在c/c++中添加.c.h的路径 即 添加后我们需要了解的函数有
LCD_Init(); LCD_Clear(颜色); LCD_SetBackColor(颜色); LCD_SetTextColor(颜色); LCD_DisplayChar(行,列,数值); LCD_DisplayStringLine(行,字符串);
void LCD_Proc(void)
{
}
USART应用程序设计
NVIC中断系统
G431有111个中断,属于内核,NVIC控制芯片中断,STM32 NVIC是CotorM4的子集,寄存器都定义在core_cm4.h的文件中,看start_stm32g431.s文件中可以查看到中断向量表。
1.中断优先级
对于中断来讲,自然优先级是在没有其他优先级,根据数的大小来判断优先级,如果数越小,优先级就越大,如果要自定义优先级,可以通过更改以下的数值来更改优先级,他们分别为抢占优先级和响应优先级。 抢占优先级有四位,相应优先级有四位。 高抢占优先级可以在具有优先级。 用hal库的函数来更改优先级即为
void HAL_NVIC_SetPriority(中断名,uint32_t PreemptPriority主优先级, uint32_t SubPriority))
硬件配置
竞赛板上的USART通过电平转换与九针的d型CN6相连,USART与UART——USB转换与USB插座cn2相连,所用的引脚对应的是PA9(usart1 tx),PA10(usart1 rx)相连。
1.配置引脚
勾选usart1会自动跳到pc4和pc5,而竞赛板上的uart是pa9和pa10,手动更改引脚为pa9和pa10,并将模式更改为Asynchronous异步模式,波特率为9600,word length为8bit,无效验位,有一个停止位,并且使能中断,调整usart的优先级,时钟的配置虽然是80mhz,但是不能用hse来配置,因为用hse来输出,是输出不了的。需要将配置换成hsi。 即配置如下:
代码处理
1.引脚时钟使能
void MX_GPIO_Init(void)
{
__HAL_RCC_GPIOF_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
}
2.USART初始化
USART_HandleTypeDef husart1;
void USART1_Init(void)
{
husart1.Instance = USART1;
husart1.Init.BaudRate = 9600;
husart1.Init.WordLength = USART_WORDLENGTH_8B;
husart1.Init.StopBits = USART_STOPBITS_1;
husart1.Init.Parity = USART_PARITY_NONE;
husart1.Init.Mode = USART_MODE_TX_RX;
husart1.Init.CLKPolarity = USART_POLARITY_LOW;
husart1.Init.CLKPhase = USART_PHASE_1EDGE;
husart1.Init.CLKLastBit = USART_LASTBIT_DISABLE;
husart1.Init.ClockPrescaler = USART_PRESCALER_DIV1;
husart1.SlaveMode = USART_SLAVEMODE_DISABLE;
if (HAL_USART_Init(&husart1) != HAL_OK)
{
Error_Handler();
}
if (HAL_USARTEx_SetTxFifoThreshold(&husart1, USART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
{
Error_Handler();
}
if (HAL_USARTEx_SetRxFifoThreshold(&husart1, USART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
{
Error_Handler();
}
if (HAL_USARTEx_DisableFifoMode(&husart1) != HAL_OK)
{
Error_Handler();
}
}
3.USART处理函数
(1)发送函数
sprintf函数需要调用<stdio.h>库
void Usart_Proc(void)
{
if(uwTick-uwTick_Usart_Set_Point<500) return;
uwTick_Usart_Set_Point=uwTick;
sprintf(str,"%04:HELLOW World.\r\n",counter);
HAL_USART_Transmit(unsigned char *)str,strlen(str),50;
HAL_Delay(500);
}
(2)单字符发送
int fputc(int ch, FILE *f)
{
HAL_UART_Transmit(&huart1, (unsigned char *)&ch, 1, 1000);
return(ch);
}
(3)接收函数
void USART1_IRQHandler(void)
{
HAL_UART_IRQHandler(&huart1);
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(uart_rx_buf[0] == 'a')
{
printf("Hello\r\n");
}
HAL_UART_Receive_IT(&huart1, uart_rx_buf, 1);
}
|