1.实现字符串数据收发函数的封装
头文件:
#ifndef __UART4_H__
#define __UART4_H__#include "stm32mp1xx_gpio.h"
#include "stm32mp1xx_rcc.h"
#include "stm32mp1xx_uart.h"void uart4_config();
void putchar(char dat);
char getchar();
void puts(char *s);
void gets(char *s);void led_init();
void LED1_CTRL(int flag);
void LED2_CTRL(int flag);
void LED3_CTRL(int flag);int Strcmp(const char *dest,const char *src);#endif
源文件:
#include "uart4.h"void uart4_config()
{//使能GPIOB\GPIOG\UART4的外设时钟RCC->MP_AHB4ENSETR |= (0x1<<1);RCC->MP_AHB4ENSETR |= (0x1<<6);RCC->MP_APB1ENSETR |= (0x1<<16);//设置PG11和PB2为管脚复用功能//PG11GPIOG->MODER &= (~(0x3<<22));GPIOG->MODER |= (0x2<<22);//PB2GPIOG->MODER &= (~(0x3<<4));GPIOG->MODER |= (0x2<<4);//设置PG11为UART4_TX功能GPIOG->AFRH &= (~(0xf<<12));GPIOG->AFRH |= (0x6<<12);//设置PB2为UART4_RX功能GPIOB->AFRL &= (~(0xf<<8));GPIOB->AFRL |= (0x8<<8);//设置串口不使能USART4->CR1 &= (~0x1);//设置8位数据位USART4->CR1 &= (~(0x1<<12));USART4->CR1 &= (~(0x1<<28));//设置没有校验位USART4->CR1 &= (~(0x1<<10));//设置时钟频率不分频USART4->PRESC &= (~0xf);//设置16倍采样USART4->CR1 &= (~(0x1<<15));//设置1位停止位USART4->CR2 &= (~(0x3<<12));//设置波特率为115200USART4->BRR = 0x22b;//使能发送器USART4->CR1 |= (0x1<<3);//使能接收器USART4->CR1 |= (0x1<<2);//使能串口USART4->CR1 |= 0x1;
}//发送单个字符
void putchar(char dat)
{//当发送寄存器中有数据时就一直阻塞while(!(USART4->ISR & (0x1<<7)));//反之没有数据则发送数据USART4->TDR = dat;//当发送的数据完成后结束发送while(!(USART4->ISR & (0x1<<6)));
}//接收单个字符
char getchar()
{//当接收寄存器中没有数据时就一直阻塞while(!(USART4->ISR & (0x1<<5)));//有数据就返回return USART4->RDR;}//发送字符串
void puts(char *s)
{while(1){if(*s=='\0'){break;}putchar(*s);s++;}//发送一个回车putchar('\n');putchar('\r');}//接收字符串
void gets(char *s)
{while(1){//循环接收单个字符*s = getchar();//当检测到回车键‘\r’被按下,结束if(*s == '\r'){break;}putchar(*s);s++;}//在接收的字符串最后补上一个'\0'*s = '\0';//发送一个'\n'表示在串口工具下一行进行显示putchar('\n');
}int Strcmp(const char *dest,const char *src)
{int i=0;while(*(dest+i) == *(src+i)){if(*(dest+i)=='\0'){break;}i++;}if(*(dest+i) - *(src+i) > 0){return *(dest+i) - *(src+i);}else if(*(dest+i) - *(src+i) < 0){return *(dest+i) - *(src+i);}else if(*(dest+i) - *(src+i) == 0){return 0;}
}
#include "uart4.h"
void led_init()
{//使能外设时钟RCC->MP_AHB4ENSETR |= (0x3<<4);RCC->MP_APB2ENSETR |= 0x1;//设置PE10为输出GPIOE->MODER &= (~(0x3<<20));GPIOE->MODER |= (0x1<<20);//设置PF10为输出GPIOF->MODER &= (~(0x3<<20));GPIOF->MODER |= (0x1<<20);//设置PE8为输出GPIOE->MODER &= (~(0x3<<16));GPIOE->MODER |= (0x1<<16);//设置PE9为输出GPIOE->MODER &= (~(0x3<<18));GPIOE->MODER |= (0x1<<18);//设置PE10为推挽输出GPIOE->OTYPER &= (~(0x1<<10));//设置PF10为推挽输出GPIOF->OTYPER &= (~(0x1<<10));//设置PE8为推挽输出GPIOE->OTYPER &= (~(0x1<<8));//设置PE9为推挽输出GPIOE->OTYPER &= (~(0x1<<9));//设置PE10为低速输出GPIOE->OSPEEDR &= (~(0x3<<20));//设置PF10为低速输出GPIOF->OSPEEDR &= (~(0x3<<20));//设置PE8为低速输出GPIOE->OSPEEDR &= (~(0x3<<16));//设置PE9为低速输出GPIOE->OSPEEDR &= (~(0x3<<18));//设置PE10没有上拉下拉电阻GPIOE->PUPDR &= (~(0x3<<20));//设置PF10没有上拉下拉电阻GPIOF->PUPDR &= (~(0x3<<20));//设置PE8没有上拉下拉电阻GPIOE->PUPDR &= (~(0x3<<16));//设置PE9没有上拉下拉电阻GPIOE->PUPDR &= (~(0x3<<18));//默认三盏灯为熄灭状态GPIOE->ODR &= (~(0x1<<10));GPIOF->ODR &= (~(0x1<<10));GPIOE->ODR &= (~(0x1<<8));//风扇GPIOE->ODR &= (~(0x1<<9));}
void LED1_CTRL(int flag)
{if(flag == 1)//亮灯{GPIOE->ODR |= (0x1<<10);}else if(flag == 0)//灭灯{GPIOE->ODR &= (~(0x1<<10));}}
void LED2_CTRL(int flag)
{if(flag == 1)//亮灯{GPIOF->ODR |= (0x1<<10);}else if(flag == 0)//灭灯{GPIOF->ODR &= (~(0x1<<10));}}
void LED3_CTRL(int flag)
{if(flag == 1)//亮灯{GPIOE->ODR |= (0x1<<8);}else if(flag == 0)//灭灯{GPIOE->ODR &= (~(0x1<<8));}}
void CH1_CTRL(int flag)
{if(flag == 1)//亮灯{GPIOE->ODR |= (0x1<<9);}else if(flag == 0)//灭灯{GPIOE->ODR &= (~(0x1<<9));}
}
主函数:
#include "uart4.h"//手动封装一个延时函数
void delay(int ms)
{int i,j;for(i=0;i<ms;i++){for(j=0;j<2000;j++){}}}
int main()
{//uart4的初始化uart4_config();led_init();//存储单个字符的容器//char a;//存储字符串的容器char buf[128];while(1){/*a = getchar(); //接收一个字符putchar(a+1); //发送一个字符,eg:发送a,输出bputchar('\r');putchar('\n');*//*gets(buf);//接收字符串puts(buf);//发送字符串*//*串口发送指令,使得LED灯/风扇工作*/gets(buf);if(Strcmp(buf,"LED1_ON") == 0){LED1_CTRL(1);}else if(Strcmp(buf,"LED1_OFF") == 0){LED1_CTRL(0);}else if(Strcmp(buf,"LED2_ON") == 0){LED2_CTRL(1);}else if(Strcmp(buf,"LED2_OFF") == 0){LED2_CTRL(0);}else if(Strcmp(buf,"LED3_ON") == 0){LED3_CTRL(1);}else if(Strcmp(buf,"LED3_OFF") == 0){LED3_CTRL(0);}else if(Strcmp(buf,"CH1_ON") == 0){CH1_CTRL(1);}else if(Strcmp(buf,"CH1_OFF") == 0){CH1_CTRL(0);}puts(buf);}return 0;
}
2.通过串口发送指令,控制LED\风扇等外设工作
#include "uart4.h"//手动封装一个延时函数
void delay(int ms)
{int i,j;for(i=0;i<ms;i++){for(j=0;j<2000;j++){}}}
int main()
{//uart4的初始化uart4_config();led_init();//存储单个字符的容器//char a;//存储字符串的容器char buf[128];while(1){/*a = getchar(); //接收一个字符putchar(a+1); //发送一个字符,eg:发送a,输出bputchar('\r');putchar('\n');*//*gets(buf);//接收字符串puts(buf);//发送字符串*//*串口发送指令,使得LED灯/风扇工作*/gets(buf);if(Strcmp(buf,"LED1_ON") == 0){LED1_CTRL(1);}else if(Strcmp(buf,"LED1_OFF") == 0){LED1_CTRL(0);}else if(Strcmp(buf,"LED2_ON") == 0){LED2_CTRL(1);}else if(Strcmp(buf,"LED2_OFF") == 0){LED2_CTRL(0);}else if(Strcmp(buf,"LED3_ON") == 0){LED3_CTRL(1);}else if(Strcmp(buf,"LED3_OFF") == 0){LED3_CTRL(0);}else if(Strcmp(buf,"CH1_ON") == 0){CH1_CTRL(1);}else if(Strcmp(buf,"CH1_OFF") == 0){CH1_CTRL(0);}puts(buf);}return 0;
}