ARM の基礎 Day4

テスト: シリアル ポート ツールで文字を入力すると次の文字が同時に表示され、文字列を入力するとその文字列が繰り返し表示されます。

main.c

#include "uart4.h"
extern void printf(const char *fmt, ...);
//extern char buffer[50] = {0};
void delay_ms(int ms)
{
	int i,j;
	for(i = 0; i < ms;i++)
		for (j = 0; j < 1800; j++);
}

int main()
{
	hal_uart_init();
	while(1)
	{
		//获取字符
		hal_put_char(hal_get_char()+1);
		//获取字符串
		hal_put_string(hal_get_string());
	}
	return 0;
}

src / uart4.c

#include "uart4.h"

extern void delay_ms(int ms);
void hal_uart_init()
{
//******RCC初始化********
	//1.使能GPIOB组控制器 MP_AHB4ENSETR[1]=1
	RCC->MP_AHB4ENSETR |=(0x1<<1);
	//2.使能GPIOG组控制器 MP_AHB4ENSETR[6]=1
	RCC->MP_AHB4ENSETR |=(0x1<<6);
	//3.使能UART4组控制器 MP_APB1ENSETR[16]=1
	RCC->MP_APB1ENSETR |=(0x1<<16);

//******GPIO引脚初始化****
	//1.设置PB2引脚为复用功能模式  MODER[5:4]=10
	GPIOB->MODER &=(~(0x3<<4));
	GPIOB->MODER |=(0x1<<5);
	//设置PB2引脚的复用功能 AFRL[11:8]=1000
	GPIOB->AFRL &=(~(0xf<<8));
	GPIOB->AFRL |=(0x1<<11);

	//2.设置PG11引脚为复用功能模式 MODER[23:22]=10
	GPIOG->MODER &=(~(0x3<<22));
	GPIOG->MODER |=(0x1<<23);
	//设置PG11引脚的复用功能 AFRH[15:12] = 0110
	GPIOG->AFRH &=(~(0xf<<12));
	GPIOG->AFRH |=(0x3<<13);
	
//******USART4串口初始化*****
	
	//判断UF是否是能
	if(USART4->CR1 & 0x1)
	{
		delay_ms(500);
		USART4->CR1 &=(~(0x1<<0));
	}

	//1.设置CR1寄存器的8位数据位,奇偶检验位 M1/M0:[28][12]=00 ; PCE[10]= 0
	USART4->CR1 &=(~(0x1<<28));
	USART4->CR1 &=(~(0x1<<12));
	USART4->CR1 &=(~(0x1<<10));
	//设置CR2寄存器的1位停止位 CR2[13:12] = 00 
	USART4->CR2 &=(~(0x3<<12));

	//2.设置CR1寄存器的串口16倍采样率 OVER8[15] = 0
	USART4->CR1 &=(~(0x1<<15));

	//3.设置PRESC寄存器的串口不分频 PRESC[3:0] = 0000 
	USART4->PRESC &=(~(0xf<<0));
	//4.设置BRR寄存器的串口波特率位115200  BRR = 0x22b
	USART4->BRR |=0x2bb;	

	//5.设置CR1寄存器的串口发送数据使能 TE[3] = 1
	USART4->CR1 &=(~(0x1<<3));
	USART4->CR1 |=(0x1<<3);
	//设置CR1寄存器的串口接受数据使能 RE[2] = 1
	USART4->CR1 &=(~(0x1<<2));
	USART4->CR1 |=(0x1<<2);
	//设置CR1寄存器的串口UE位使能
	USART4->CR1 |=(0x1<<0);
}

//发送一个字符
void hal_put_char(const char str)
{
	//判断发送数据寄存器是否为空 ISR[7]
	//读0:表示发送数据寄存器满,需要等待
	//读1:表示发送数据寄存器为空,发送下一个字节数据
	while(!(USART4->ISR &=(0x1<<7)));
	//将要发送的数据,存入发送数据寄存器中
	USART4->TDR = str;
	//发送数据寄存器是否完成发送 ISR[6]
	while(!(USART4->ISR &=(0x1<<6)));
}

//发送字符串
void hal_put_string(const char* string)
{	
	while(*string)
	{
		//一个一个字符发送
		hal_put_char(*string++);
	}
	hal_put_char('\n');
}

//接收字符
char hal_get_char()
{
	char str1;
	//判断接收数据寄存器中是否有数据可读 ISR[5]
	while(!(USART4->ISR &=(0x1<<5)));
	str1=USART4->RDR;
	return str1;
}

char str2[128]={0};
//接收字符串
char* hal_get_string()
{
	//循环进行接收
	unsigned int i;
	for(i=0;i<sizeof(str2)-1;i++)
	{
		str2[i]=hal_get_char();
		hal_put_char(str2[i]);
		if(str2[i]=='\r')
			break;
	}
	str2[i]='\0';
	hal_put_char('\n');
	hal_put_char('\r');
	return str2;
}

インクルード / uart4.h

#include "uart4.h"

extern void delay_ms(int ms);
void hal_uart_init()
{
//******RCC初始化********
	//1.使能GPIOB组控制器 MP_AHB4ENSETR[1]=1
	RCC->MP_AHB4ENSETR |=(0x1<<1);
	//2.使能GPIOG组控制器 MP_AHB4ENSETR[6]=1
	RCC->MP_AHB4ENSETR |=(0x1<<6);
	//3.使能UART4组控制器 MP_APB1ENSETR[16]=1
	RCC->MP_APB1ENSETR |=(0x1<<16);

//******GPIO引脚初始化****
	//1.设置PB2引脚为复用功能模式  MODER[5:4]=10
	GPIOB->MODER &=(~(0x3<<4));
	GPIOB->MODER |=(0x1<<5);
	//设置PB2引脚的复用功能 AFRL[11:8]=1000
	GPIOB->AFRL &=(~(0xf<<8));
	GPIOB->AFRL |=(0x1<<11);

	//2.设置PG11引脚为复用功能模式 MODER[23:22]=10
	GPIOG->MODER &=(~(0x3<<22));
	GPIOG->MODER |=(0x1<<23);
	//设置PG11引脚的复用功能 AFRH[15:12] = 0110
	GPIOG->AFRH &=(~(0xf<<12));
	GPIOG->AFRH |=(0x3<<13);
	
//******USART4串口初始化*****
	
	//判断UF是否是能
	if(USART4->CR1 & 0x1)
	{
		delay_ms(500);
		USART4->CR1 &=(~(0x1<<0));
	}

	//1.设置CR1寄存器的8位数据位,奇偶检验位 M1/M0:[28][12]=00 ; PCE[10]= 0
	USART4->CR1 &=(~(0x1<<28));
	USART4->CR1 &=(~(0x1<<12));
	USART4->CR1 &=(~(0x1<<10));
	//设置CR2寄存器的1位停止位 CR2[13:12] = 00 
	USART4->CR2 &=(~(0x3<<12));

	//2.设置CR1寄存器的串口16倍采样率 OVER8[15] = 0
	USART4->CR1 &=(~(0x1<<15));

	//3.设置PRESC寄存器的串口不分频 PRESC[3:0] = 0000 
	USART4->PRESC &=(~(0xf<<0));
	//4.设置BRR寄存器的串口波特率位115200  BRR = 0x22b
	USART4->BRR |=0x2bb;	

	//5.设置CR1寄存器的串口发送数据使能 TE[3] = 1
	USART4->CR1 &=(~(0x1<<3));
	USART4->CR1 |=(0x1<<3);
	//设置CR1寄存器的串口接受数据使能 RE[2] = 1
	USART4->CR1 &=(~(0x1<<2));
	USART4->CR1 |=(0x1<<2);
	//设置CR1寄存器的串口UE位使能
	USART4->CR1 |=(0x1<<0);
}

//发送一个字符
void hal_put_char(const char str)
{
	//判断发送数据寄存器是否为空 ISR[7]
	//读0:表示发送数据寄存器满,需要等待
	//读1:表示发送数据寄存器为空,发送下一个字节数据
	while(!(USART4->ISR &=(0x1<<7)));
	//将要发送的数据,存入发送数据寄存器中
	USART4->TDR = str;
	//发送数据寄存器是否完成发送 ISR[6]
	while(!(USART4->ISR &=(0x1<<6)));
}

//发送字符串
void hal_put_string(const char* string)
{	
	while(*string)
	{
		//一个一个字符发送
		hal_put_char(*string++);
	}
	hal_put_char('\n');
}

//接收字符
char hal_get_char()
{
	char str1;
	//判断接收数据寄存器中是否有数据可读 ISR[5]
	while(!(USART4->ISR &=(0x1<<5)));
	str1=USART4->RDR;
	return str1;
}

char str2[128]={0};
//接收字符串
char* hal_get_string()
{
	//循环进行接收
	unsigned int i;
	for(i=0;i<sizeof(str2)-1;i++)
	{
		str2[i]=hal_get_char();
		hal_put_char(str2[i]);
		if(str2[i]=='\r')
			break;
	}
	str2[i]='\0';
	hal_put_char('\n');
	hal_put_char('\r');
	return str2;
}

おすすめ

転載: blog.csdn.net/weixin_57039874/article/details/130866343