当前位置:网站首页>In depth understanding of STM32 serial port experiment (register) [nanny level tutorial]
In depth understanding of STM32 serial port experiment (register) [nanny level tutorial]
2022-06-26 11:10:00 【The road is difficult at night】

First look at this picture ,, It can be seen that USART_RX_STA Similar to a 16 Bit register , front 14 Bits store data , The latter two tests respectively 0X0D and 0X0A.
Next, inside analysis :
void uart_init(u32 pclk2,u32 bound)
{
float temp;
u16 mantissa;
u16 fraction;
temp=(float)(pclk2*1000000)/(bound*16);// obtain USARTDIV
mantissa=temp; // Get the whole part
fraction=(temp-mantissa)*16; // Get the fraction
mantissa<<=4;
mantissa+=fraction;
RCC->APB2ENR|=1<<2; // Can make PORTA Port clock
RCC->APB2ENR|=1<<14; // Enable serial clock
GPIOA->CRH&=0XFFFFF00F;//IO State settings
GPIOA->CRH|=0X000008B0;//IO State settings
RCC->APB2RSTR|=1<<14; // Reset serial port 1
RCC->APB2RSTR&=~(1<<14);// Stop reset
// Baud rate setting
USART1->BRR=mantissa; // Baud rate setting
USART1->CR1|=0X200C; //1 Bit stop , No parity bit .
#if EN_USART1_RX // If enabled, receive
// Enable receive interrupt
USART1->CR1|=1<<5; // Receive buffer non air interrupt enable
MY_NVIC_Init(3,3,USART1_IRQn,2);// Group 2, Lowest priority
#endif
}temp=(float)(pclk2*1000000)/(bound*16); This is a formula , Because the serial port is enabled 1, And serial port 1 Is in APB2ENR In the register ( Other serial ports are in register APB1ENR Inside ), because APB2 The frequency of the general bit 72M, and APB1 The frequency of the general bit 36M.
So here pclk2 by 72M, and bound Is the baud rate you need to set .
mantissa = temp The role of is just : In order to find the decimal part next
fraction=(temp-mantissa)*16; // Get the fraction
mantissa<<=4;These two lines of code are to convert the integer part and decimal part of the decimal system , Convert to 16 Base number . Then it is stored in the baud rate register . Then enable the serial port 1 and PORTA The clock ( Serial port 1 corresponds to IO The mouth is PA9,PA10, You need to hold the jump cap together ).
And then IO Set the mouth to zero , Then set it to one input and one output respectively ,
USART1->CR1|=0X200C; Set to enable the serial port 8 One word long 1 Stop bits (USART_CR2 in [13:12] The default is “0”)
MY_NVIC_Init(3,3,USART1_IRQn,2)
Group them into groups 2 Inside , Preemption priority at this time : The response priority is = 2:2, namely (00-11) Four situations , and 3:3 The arrangement of the selected group 2 The case with the lowest priority . In this way, the baud rate assignment above can be performed first , And serial port enable and so on , Finally, run this line of code .
Let's move on to the next section :
u16 USART_RX_STA=0; // Receive status flag
void USART1_IRQHandler(void)
{
u8 res;
#if SYSTEM_SUPPORT_OS // If SYSTEM_SUPPORT_OS It's true , Support is needed OS.
OSIntEnter();
#endif
if(USART1->SR&(1<<5)) // Data received
{
res=USART1->DR;
if((USART_RX_STA&0x8000)==0)// Reception is not complete
{
if(USART_RX_STA&0x4000)// received 0x0d
{
if(res!=0x0a)USART_RX_STA=0;// Receive error , restart
else USART_RX_STA|=0x8000; // The reception is complete
}
else // I haven't received 0X0D
{
if(res==0x0d)USART_RX_STA|=0x4000;
else
{
USART_RX_BUF[USART_RX_STA&0x3fff]=res;
USART_RX_STA++;
if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;// Receiving data error , Start receiving again
}
}
}
}The starting stage : USART_RX_STA=0, Mark of acceptance status .
First pass the status register SR Of RXNE Is it 1, yes 1 Data is received , And vice versa . Then this defines a res Variable to receive a byte from the data register , And then at this point USART_RX_STA by 0, And 0X8000 Conduct & operation , The result is 0, Did not receive , Then continue to judge ,0X4000 Operation and operation , See if it's 0, It is also to judge whether to accept the road 0X0D, If not , Then you can put this res Variables are stored in the array , At this time USART_RX_STA by 0 And 0X3fff Conduct & operation , You will find that , Because his former 14 Bits are data bits , So you will find that the first variable will be stored in BUF[0] Inside , Maybe the logic is like this :

So each byte is stored in a specific array bit .
if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;// Receiving data error , Start receiving again
When the array is out of bounds , Will start over .
Then it will continue to cycle , When the data bits are full , Next res What it accepts is 0X0D, Judge as above USART_RX_STA Whether you have received 0X0A and 0X0D.
Then perform :
if(res==0x0d)USART_RX_STA|=0x4000;take USART_RX_STA The fifteenth position of the becomes 1,, Next, go to the next cycle , This time, res The value received is 0X0A,
Then judge and enter
if(USART_RX_STA&0x4000)// received 0x0d
{
if(res!=0x0a)USART_RX_STA=0;// Receive error , restart
else USART_RX_STA|=0x8000; // The reception is complete
}So execute USART_RX_STA|=0x8000, bring USART_RX_STA The 16th position of the becomes 1.
Next, let's look at the main function :
int main(void)
{
u8 t;
u8 len;
u16 times=0;
Stm32_Clock_Init(9); // System clock settings
delay_init(72); // Delay initialization
uart_init(72,9600); // The serial port is initialized to 9600
LED_Init(); // Initialization and LED Connected hardware interface
while(1)
{
if(USART_RX_STA&0x8000)
{
len=USART_RX_STA&0x3fff;// The length of data received this time
printf("\r\n The message you sent is :\r\n");
for(t=0;t<len;t++)
{
USART1->DR=USART_RX_BUF[t];
while((USART1->SR&0X40)==0);// Wait for the end of sending
}
printf("\r\n\r\n");// Insert newline
USART_RX_STA=0;
}else
{
times++;
if(times%5000==0)
{
printf("\r\nALIENTEK MiniSTM32 Development board Serial port experiment \r\n");
printf(" The punctual atoms @ALIENTEK\r\n\r\n\r\n");
}
if(times%200==0)printf(" Please input data , End with enter \r\n");
if(times%30==0)LED0=!LED0;// flashing LED, Indicates that the system is running .
delay_ms(10);
}
}
}if(USART_RX_STA&0x8000) Determine whether it has received 0X0A
len=USART_RX_STA&0x3fff; For a simple example, at this time USART_RX_STA by 1100000000000011 and 0X3fff Conduct & operation , And what you get is 3, Naturally, it indicates the size of the current array .
The last stage , Focus on understanding the following two lines of code :
USART1->DR=USART_RX_BUF[t];
while((USART1->SR&0X40)==0);// Wait for the end of sending The analysis is as follows : Store the information in each group into the data register , At this time, the data register gives data to TDR, When sending messages , It is sent one by one , Each data frame has a start bit , Data bits , And stop bit , When it is detected that the detailed information of the data register has been sent ( I gave it to you completely TDR), At this time, the status register is TXE Becomes 1, When detected TXE by 1 after ,TC It will also become 1( The system automatically ). So the second line will detect the second line of the status register 6 Whether a is 1 To determine whether this byte was successfully sent .
From this came , Direct judgment TXE You can also judge whether the transmission is completed
So the code can be changed to :
for(t=0;t<len;t++)
{
USART1->DR=USART_RX_BUF[t];
while((USART1->SR&0X80)==0);// Wait for the end of sending
}边栏推荐
- Machine Learning Clustering - Experimental Report
- 再获认可!知道创宇入选“业务安全推进计划”首批成员单位
- Moore vote, leetcode169, leetcode229
- ACK攻击是什么意思?ACK攻击怎么防御?
- ceph运维常用指令
- 服务器单、双向可调一键互信脚本!
- redux相关用法
- [software project management] sorting out knowledge points for final review
- 关于印发《深圳市福田区支持战略性新兴产业和未来产业集群发展若干措施》的通知
- 9、 Beautify tables, forms, and hyperlinks
猜你喜欢
随机推荐
Redis knowledge mind map
Expand and collapse too high div
2021 Q3-Q4 Kotlin Multiplatform 使用现状 | 调查报告
Splicing full paths and uploading multiple pictures of laravel admin when laravel uses OSS
SVN 安装配置
Machine Learning Clustering - Experimental Report
2020.7.6 interview with fence network technology company
【深度学习理论】(6) 循环神经网络 RNN
ISO 26262 - 2 functional safety concept
Build document editor based on slate
consul微服务治理中心踩坑
FasterRCNN
c语言 --- 运算符和表达式
Will updating a large amount of data in Oracle cause the undo space to explode
Matrix fast power notes
Unity使用SteamVRPlugin时如何不让其他Camera位置和旋转收到SteamVRPlugin控制
Nacos2.x.x start error creating bean with name 'grpcclusterserver';
[deep learning theory] (7) long and short term memory network LSTM
02 linked list of redis data structure
loggie 编码以及换行符测试








