一、实现的功能
- ①LED1 ~ LED8显示0~255的二进制数,每过1s添加1;
- ②LCD把LED显示的数字实时显示到LCD屏幕上面;
- ③使用串口使用三种不同的方式把实时数据打印出来;
- ④运行串口接收中断,通过串口助手更新实时数据;
二、根据功能实现代码
1、主文件main.c
#include"key.h"
#include"led.h"
#include"lcd.h"
#include "usart.h"
unsigned char ucSec,ucSec1;
unsigned char pucStr[21];
unsigned char pucRcv[5] = " \0 ",ucRno = 3;
unsigned long ulTick_ms;
void LCD_Proc(void);
void USART_Proc(void);
int main(void)
{
SysTick_Config(72000);
KEY_Init();
LED_Init();
STM3210B_LCD_Init();
LCD_Clear(Blue);
LCD_SetBackColor(Blue);
LCD_SetTextColor(White);
USART2_Init(9600);
while(1)
{
LED_Disp(ucSec);
LCD_Proc();
USART_Proc();
}
}
void LCD_Proc(void)
{
sprintf((char*)pucStr," %02u ",ucSec);
LCD_DisplayStringLine(Line5,pucStr);
}
void USART_Proc(void)
{
if(ucSec !=ucSec1)
{
ucSec1 = ucSec;
USART_SendChar(USART2,ucSec/10+0x30);
USART_SendChar(USART2,ucSec%10+0x30);
USART_SendChar(USART2,' ');
pucRcv[0] = ucSec/10+0x30;
pucRcv[1] = ucSec%10+0x30;
USART_SendString(USART2,pucRcv);
printf(" %s\r\n",pucRcv);
}
if(ucRno ==5)
{
ucRno = 3;
ucSec = (pucRcv[3]-'0')*10 + pucRcv[4]-'0';
}
}
void SysTick_Handler(void)
{
ulTick_ms++;
if(ulTick_ms % 1000 ==0)
ucSec++;
}
void USART2_IRQHandler(void)
{
pucRcv[ucRno++] = USART_ReceiveData(USART2);
}
主函数分析:?? ?? ??
- 通过USART_SendChar()把实时数据的每一个位转换成字符,通过串口打印到串口助手;
- 把实时数据的每一个位转换成字符保存到字符数组中,通过USART_SendString()打印字符数组(即字符串);
- 通过重写printf()函数实现串口的打印;
- 把串口接收到的字符保存到数组中,当发送的了两位数给开发板时,计算串口发送数据(-‘0’),更新正在计算的值;
- 中断服务函数的命名必须按照向量表进行定义,否则程序会卡死在启动文件的B .处,可到startup_stm32f10x_md.s启动文件复制向量表名;
2、USART头文件“usart.h”
#include "stm32f10x.h"
#include "stdio.h"
void USART2_Init(unsigned long ulBaud);
unsigned char USART_SendChar(USART_TypeDef* USARTx,unsigned char ucChar);
void USART_SendString(USART_TypeDef* USARTx,unsigned char* pucStr);
简要分析:?? ??
- 声明了USART2的初始化和串口发送字符和字符串函数;
3、USART源文件“usart.c”
#include "usart.h"
void USART2_Init(unsigned long ulBaud)
{
GPIO_InitTypeDef GPIO_InitStruct;
USART_InitTypeDef USART_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_Mode= GPIO_Mode_AF_PP;
GPIO_Init(GPIOA,&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStruct.GPIO_Mode= GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA,&GPIO_InitStruct);
USART_InitStruct.USART_BaudRate = ulBaud;
USART_InitStruct.USART_WordLength = USART_WordLength_8b;
USART_InitStruct.USART_StopBits = USART_StopBits_1;
USART_InitStruct.USART_Parity = USART_Parity_No;
USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_Init(USART2,&USART_InitStruct);
USART_Cmd(USART2,ENABLE);
USART_ITConfig(USART2,USART_IT_RXNE,ENABLE);
NVIC_InitStruct.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority =0;
NVIC_InitStruct.NVIC_IRQChannelSubPriority =0;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
}
unsigned char USART_SendChar(USART_TypeDef* USARTx,unsigned char ucChar)
{
while(!USART_GetFlagStatus(USARTx,USART_FLAG_TXE));
USART_SendData(USARTx,ucChar);
return ucChar;
}
void USART_SendString(USART_TypeDef* USARTx,unsigned char* pucStr)
{
while(*pucStr !='\0')
USART_SendChar(USARTx,*pucStr++);
}
int fputc(int ch,FILE *f)
{
return(USART_SendChar(USART2,ch));
}
简要分析:?? ??
- 串口初始化:①把PA2(TX2)、PA3(RX2)分别初始化为复用推挽输出和浮空输入 → ②配置USART2的参数 → ③配置NVIC USART2嵌套中断的参数;
- 配置USART2的详细步骤:①声明USART_InitTypeDef结构体变量→②使能端口时钟(挂在APB1总线) → ③配置串口的波特率、默认8个数据位、1个停止位、无校验,允许Rx与Tx,无硬件数据流控制 → ④调用Init函数初始化结构体;
- 配置NVIC USART2中断的详细步骤:①声明NVIC_InitTypeDef结构体变量 → ②使能USART2和接收(发送)中断 → ③配置NVIC结构体的USART2中断向量,抢占优先级、子优先级、IRQ通道使能→ ④调用Init函数初始化NVIC结构体;
- 定义发送字符函数,首先使用while获取到发送标志位,然后调用固件库USART_SendData把字符发出去,而发送字符串就是把字符数组的每一位字符发送出去;
- 覆写printf为串口打印输出函数,需要在Target中勾选“Use MicroLIB” 才能正常使用;
三、实现功能过程的注意与学习点
1、注意点
- 中断服务函数的命名必须按照向量表的定义,否则无法正常中断;
- 覆写printf为串口打印输出函数,需要在Target中勾选“Use MicroLIB” 才能正常使用;
2、学习的知识点
- ①字符 - ‘0’ = 数字,掌握字符与数字的转换;
- ②掌握三种串口打印实时数据的方法;
- ③学会通过固件库配置串口与中断的初始化步骤;
- ①实现printf的覆写,调用printf实现串口的打印输出;
?? ?? ?? ?? ?? ??
|