传输方式
STM32F407传输方式有两种,并行传输和串行传输。
并行传输相当于一个字节8位,用8根线,8个引脚同时传输;
串行传输是一根线,通过一位一位进行传输,将数据发送出去。
一般都采用串行传输,速度快,效率高,方便,而不采用并行传输。
串行传输
串行传输又分为两种方式
- 同步传输
- 异步传输
同步传输一般指需要一根额外的时钟线,传输双方通过时钟线来确认数据位。
异步传输一般只需要数据线,通过特定的报文格式,来确认数据。
传输速度用波特率表示,如115200bps,表示每秒传输的数据数量。
USART
STM32通过USART串口来进行串行数据传输。
USART的使用方式
- 配置USART的时钟
- 配置GPIO,设置串口复用功能
- 配置串口
- 配置中断
- 配置串口中断
- 使能串口
例子如下
void my_usart_init(void)
{
/* USART1 在APB2总线上
USART1的TX 在 PA9
USART1的RX 在 PA10
*/
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//通过AHB1总线使能GPIOA组的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);//通过APB2总线使能USART1的时钟
GPIO_InitTypeDef Gpio_Value;
Gpio_Value.GPIO_Mode = GPIO_Mode_AF;//选择的是复用模式
Gpio_Value.GPIO_OType = GPIO_OType_PP;//选择推挽输出
Gpio_Value.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;//选择管脚9和10
Gpio_Value.GPIO_PuPd = GPIO_PuPd_NOPULL;//选择无上拉无下拉
Gpio_Value.GPIO_Speed = GPIO_Speed_50MHz;//选择50MHz
GPIO_Init(GPIOA, &Gpio_Value);//按照上述配置初始化GPIOA组的管脚
// 告诉GPIO 该引脚 复用的是什么功能
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);//为PA9选择USART1的复用功能
GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);//为PA10选择USART1的复用功能
//初始化USART1
USART_InitTypeDef Usart_Value;
Usart_Value.USART_BaudRate = 115200;//选择115200波特率
Usart_Value.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//关闭硬件流控
Usart_Value.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//选择发送和接收模式
Usart_Value.USART_Parity = USART_Parity_No;//没有奇偶校验
Usart_Value.USART_StopBits = USART_StopBits_1;//1个停止位
Usart_Value.USART_WordLength = USART_WordLength_8b;//8个数据位
USART_Init(USART1, &Usart_Value);//按照上述配置初始化USART1
//配置中断
MY_NVIC_INIT();
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //配置USART1的中断方式,USART_IT_RXNE 表示接受到数据
USART_Cmd(USART1, ENABLE);//使能USART1的功能
}
static void MY_NVIC_INIT(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitTypeDef Nvic_Value;
Nvic_Value.NVIC_IRQChannel = USART1_IRQn; //配置USART1的中断
Nvic_Value.NVIC_IRQChannelCmd = ENABLE;
Nvic_Value.NVIC_IRQChannelPreemptionPriority = 2;
Nvic_Value.NVIC_IRQChannelSubPriority = 2;
NVIC_Init(&Nvic_Value);
}
void my_usart_send_char(unsigned char data)
{
USART_SendData(USART1, data); //发送一个字节数据
while(USART_GetFlagStatus(USART1, USART_FLAG_TC) != SET); //TC 位表示 数据发送是否完成,这里的SET表示 数据发送完成
USART_ClearFlag(USART1, USART_FLAG_TC);
}
void my_usart_send_string(unsigned char * buff)
{
while(*buff)
{
my_usart_send_char(*buff);
buff++;
}
}
接收到数据后的操作:
void USART1_IRQHandler(void)
{
if(USART_GetITStatus(USART1, USART_IT_RXNE) == SET) //再确认下当前数据接收完了
{
my_usart_send_char(USART_ReceiveData(USART1)); //将接收的数据再发送出去
USART_ClearITPendingBit(USART1, USART_IT_RXNE); //清除中断标志位
}
}
main函数
int main(void)
{
my_led_init();
key_init();
my_systemclk_init();
my_usart_init();
my_delay_ms(100);
my_usart_send_string("hello world");
my_usart_send_char('B');
my_usart_send_string("串口程序测试!!");
while(1) {
my_usart_send_char('A');
my_delay_ms(1000);
}
}