?串口發送指令控制硬件工作
uart1.h
#ifndef __UART1_H__
#define __UART1_H__
#include "stm32mp1xx_gpio.h"
#include "stm32mp1xx_rcc.h"
#include "stm32mp1xx_uart.h"
void all_led_init();
void led1_on();
void led2_on();
void led3_on();
void led1_off();
void led2_off();
void led3_off();
void uart4_init();
void myputchar(char i);
char mygetchar();
char *gets();
void puts(char *s);
int mystrcmp(char *p1,char *p2);
#endif
?uart1.c
#include"uart1.h"
char buf[51]={0};
//串口數據初始化
void uart4_init()
{//1.UART4和GPIOB\GPIOG的時鐘使能RCC->MP_AHB4ENSETR|=(0x1<<1);//使能GPIOB時鐘RCC->MP_AHB4ENSETR|=(0x1<<6);//使能GPIOG時鐘RCC->MP_AHB4ENSETR|=(0x1<<16);//使能UART4的時鐘//2.設置PB2和PG11的管腳復用GPIOB->MODER&=(~(0x3<<4));GPIOB->MODER|=(0x2<<4);//設置復用GPIOB->AFRL &=(~(0xF<<8));GPIOB->AFRL |=(0x8<<8);//設置uart4功能復用//設置PB2和PG11的管腳復用GPIOG->MODER&=(~(0x3<<22));GPIOG->MODER|=(0x2<<22);//設置復用GPIOG->AFRH &=(~(0xF<<12));GPIOG->AFRH |=(0x6<<12);//設置uart4功能復用//3.先去設置串口禁用,方便設置數據格式USART4->CR1&=(~0x1);//4.設置8位數據位
USART4->CR1&=(~(0x1<<28));
USART4->CR1&=(~(0x1<<12));//5.設置沒有奇偶校驗USART4->CR1&=(~(0x1<<10));//6.設置16倍采樣USART4->CR1&=(~(0x1<<15));//7.設置1位停止位USART4->CR2&=(~(0x3<<12));//8.設置1分頻USART4->PRESC&=(~(0xF));//9.設置波特率115200bpsUSART4->BRR|=0x22B;//10.發送器、接收器使能USART4->CR1|=(0x1<<3);USART4->CR1|=(0x1<<2);//11.USART4->CR1|=(0x1);//
}
void myputchar(char c)
{//1.判斷TDR寄存器是否為空,如果為空,向TDR寄存器寫入數據while(!(USART4->ISR&(0x1<<7)));USART4->TDR=c;////阻塞等待數據傳輸完成,函數返回while(!(USART4->ISR&(0x1<<6)));//}
char mygetchar()
{ char c;//判斷RDR寄存器是否有就緒的數據,如果有就讀取,否則等待while(!(USART4->ISR&(0x1<<5)));c=USART4->RDR;return c;
}
//輸出一個字符串
void puts(char *s)
{while(*s){myputchar(*s);s++;}myputchar('\n');myputchar('\r');
}//讀取一個字符串
char *gets()
{unsigned int i;for(i=0;i<50;i++){buf[i]=mygetchar();myputchar(buf[i]);if(buf[i]=='\r')break;}buf[i]='\0';myputchar('\n');return buf;
}
void all_led_init()
{// 1.使能外設時鐘RCC->MP_AHB4ENSETR|=(0X3<<4);// 2.設置PF10 PE10 PE8為輸出輸出GPIOE->MODER &= (~(0x3 << 20));GPIOE->MODER |= (0x1 << 20);GPIOF->MODER &= (~(0x3 << 20));GPIOF->MODER |= (0x1 << 20);GPIOE->MODER &= (~(0x3 << 16));GPIOE->MODER |= (0x1 << 16);// 3.設置推挽輸出GPIOE->OTYPER &= (~(0x1 << 10));GPIOF->OTYPER &= (~(0x1 << 10));GPIOE->OTYPER &= (~(0x1 << 8));// 4.設置輸出速度為低速GPIOE->OSPEEDR &= (~(0x3 << 20));GPIOF->OSPEEDR &= (~(0x3 << 20));GPIOE->OSPEEDR &= (~(0x3 << 16));// 5.設置無上拉下拉GPIOE-> PUPDR&= (~(0x3 << 20));GPIOF-> PUPDR&= (~(0x3 << 20));GPIOE-> PUPDR&= (~(0x3 << 16));
}
void led1_on()
{GPIOE->ODR |= (0x1 << 10);
}
void led2_on()
{GPIOF->ODR |= (0x1 << 10);
}
void led3_on()
{GPIOE->ODR |= (0x1 << 8);
}void led1_off()
{GPIOE->ODR &= (~(0x1 << 10));
}
void led2_off()
{GPIOF->ODR &= (~(0x1 << 10));
}
void led3_off()
{GPIOE->ODR &= (~(0x1 << 8));
}
int mystrcmp(char *p1,char *p2)
{int ret;while(*p1 == *p2 && *p1 != '\0' && *p2 != '\0'){p1++;p2++;}ret = *p1 - *p2; // 返回值if(ret==0)return 0;elsereturn 1;
}
?main.c
#include"uart1.h"
//封裝延時函數
void delay(int ms)
{int i,j;for(i=0;i<ms;i++){for(j=0;j<2000;j++);}
}
int main()
{//串口的初始化uart4_init();char *str;all_led_init();//LED初始化//現象是發送一個a串口工具打印一個bwhile(1){myputchar('\n');myputchar('\r');//2.從串口讀取一個字符串str=gets();puts(str);//3.回顯輸入的字符串if(mystrcmp(str,"led1_on")==0){led1_on();}else if(mystrcmp(str,"led1_off")==0){led1_off();}else if(mystrcmp(str,"led2_on")==0){led2_on();}else if(mystrcmp(str,"led2_off")==0){led2_off();}else if(mystrcmp(str,"led3_on")==0){led3_on();}else if(mystrcmp(str,"led3_off")==0){led3_off();}}return 0;
}