Self introductionWhy do you write a self-introduction? As the saying goes, Light said do not practice false bashi, light practice does not say silly bashi, because I have been very conceited, feel what things can be quickly started (of course, non-counterpart professional knowledge requirements of high skills excepted), if I do not show this conceit, feeling will suppress internal injuries.I graduated in 2015 from the University of computer, the ideal is to enter a foreign game company, but the ideal is very plump, the reality is very skinny, to Ubisoft, 2k Game, Gameloft, EA have voted resumes, but are ruthless pass off (in this spit groove, Do these companies really want to recruit undergraduates on campus? Obviously the computer graphics of graduate students have become the requirements of these companies for undergraduates. Later graduated also did not find a job, in order to self-reliance, casually went to the home electrical company, that is, my present company.This is the home to create the company, the business is to do intelligent emergency evacuation lighting system this piece, although Mister also said to me later to engage in the internet of things, but I feel this is the original trick me to the company. The company's understanding of software development basically stay in 0, also do not want to pay for a senior software engineer, so I became the company's only one, both in charge of high-level program development, and the development of the bottom. Although in the school did not use C #, but the language has similarities, so for now the company's host computer program development is still well, but the experience of the underlying development is basically useless. Although before in a company's probation period, I began to touch the microcontroller, but because I do not like to copy someone else's code, so when the company wants me to 51 single-chip computer to write a serial communication, browse the next STC data Manual on the ambiguous development, and then stuck, compared to the online programs, Feel their steps are not wrong ah, this incident let self-proclaimed learning ability strong I was hit, so from that company resigned, now in retrospect, perhaps I did not notice that 51 single-chip serial port baud rate generator can only use T1, and I have been using T0 as a baud rate generator.Recently began to contact the STM32 series chip, because there is a firmware library for the operation of the underlying register is encapsulated, very close to advanced programming, learning and easy to use, and now many mobile chips are based on the ARM architecture, So learning arm chip is also knocking open the door of many large enterprises (I want to use it to open the doors of Huawei). Problem descriptionOnline Search "STM32 BUG", will be found to plague many STM32 developers of two problems, one is about I²c, and the other is about the serial port to send data loss of the first frame of the problem. Because I also touch the i²c, so the first question is what's going on I don't know. Although the second problem, the Internet also has the answer to the cause of the problem, and follow these answers in the way to write a serial sender can prevent the loss of the first frame of data. Because I don't want to copy other people's programs, so in a fortuitous coincidence, I found another explanation of the problem, and this explanation overturned the explanations provided by netizens. Problem analysisThe following is a description of the process of sending data to the serial port by the official STM32 reference manual:
- Activating the Usart by placing the UE bit on the USART_CR1 register
- Programming USART_CR1 the M-bit to define the word length.
- The number of bits in the USART_CR2 that are programmed to stop bits.
- If you are using multi-buffer communication, configure the DMA enable bit (DMAT) in the USART_CR3. Configure the DMA register as described in multi-buffer communication.
- Sets the TE bit in the USART_CR1, sending a free frame as the first data send.
- Use the USART_BRR register to select the required baud rate.
- Writes the data to be sent into the USART_DR register (this action clears the TXE bit). Repeat step 7 for each data you want to send, in the case of only one buffer.
For the steps that cause the serial port to lose data I agree with the netizen that, in step 5, a free frame is sent as the first data send when the position te is placed. However, I do not agree with the netizen about why the free frame will cause the user data to lose the first frame.The views of netizens can be summed up as two words, covering. This is the popular view of netizens, http://blog.csdn.net/kevinhg/article/details/40991655, see some netizens quoted this blog, and a lot of netizens ' views are basically consistent with this blog. From this blog can be seen, the Netizen think is in sending the first data when, did not read USART_SR, so TC is still in place, in writing the second data, when the first data is overwritten.So I followed the explanation in this blog, wrote a sender program, the key code is as follows:
/* Send data */if (Usart_getflagstatus (USART3,USART_FLAG_TC)!=reset) {if (Txcount3<buf3_len) {Usart_senddata (USART3, RX3_BUF[TXCOUNT3]); Txcount1=usart_getflagstatus (USART3,USART_FLAG_TC); txcount3++;} Else{usart_itconfig (usart3,usart_it_txe,disable);//Send complete, close TXE, avoid TDR air Break}}
If I read the status of USART_SR and then send the first data, according to the official reference manual, when the TC is zeroed out, then there is no second data overwrite the first data, but in fact, the first frame of data is still missing. Netizens may say that, in this way, writing the first data to USART_DR does not allow the TC to clear, then the following is the program I modified, mainly to monitor the USART_DR to write the first data after the TC is cleaned:
if (Usart_getflagstatus (USART3,USART_FLAG_TC)!=reset) {if (Txcount3<buf3_len) {Usart_senddata (USART3,rx3_buf[ TXCOUNT3]); Txcount1=usart_getflagstatus (USART3,USART_FLAG_TC); txcount3++;} Else<span style= "color: #ff6666;" ></span>{usart_itconfig (usart3,usart_it_txe,disable);//Send complete, close TXE, avoid TDR air Break}}
Debug as follows:
As you can see from the Watch window, txcount3=0, I am sending the first data, and after writing the first data to USART_DR, the txcount1=0, stating that TC is cleared, is consistent with the official reference manual, then there should be no second data covering the first data.Because of the lack of understanding of the specific implementation of the hardware, my point of view is just a guess. After placing TE, TC and TXE are both set (this explains why TE is placed and enables TXE,TC to continue into the interrupt program), and sends a frame of free frame as the first data, according to the official reference manual, the TC set indicates that the send shift register is empty and can write data to USART_DR , it is supposed that the user's first data can be written at this time, but the real situation is that the sending shift register is also equipped with the data of the free frame, that is, the idle frame is not sent to complete (this explains why the delay period of time after the placement of TE, the first data will not be lost, because the time delay during the completion of When the idle frame has not yet been sent, it is speculated that the official provides the hardware protection of the shift register, that is, even if the TC is set, the data in the USART_DR will not be loaded into the sending shift register, but is ignored. The hardware protection condition of the sending shift register is inferred: Shift register for send complete, TC has been set, although want to write a program verification, but TC can only be placed by the hardware. The first data is written into the TDR:
/* Send data */if (Usart_getflagstatus (USART3,USART_FLAG_TXE)!=reset) {if (Txcount3<buf3_len) {Usart_senddata (USART3, RX3_BUF[TXCOUNT3]); Txcount1=usart_getflagstatus (USART3,USART_FLAG_TXE); txcount3++;} Else{usart_itconfig (usart3,usart_it_txe,disable);//Send complete, close TXE, avoid TDR air Break}}
The inside of the If, which indicates that the TXE was set before the first data is written, txcount1=0, or Txe, is zeroed, indicating that the first data is written to the TDR.so the details of the serial port are further supplemented on the basis of previous speculation. When the sending shift register is sent, the status of the TC is read first, and if the TC is set, the serial port ignores the data in the TDR (this also conforms to the official reference document description, when the TC is set, the Send shift register is empty, the write data to the USART_DR is placed directly into the send shift register, The TDR stored the first data is ignored, which also explains the first data loss problem), if the TC is not set, the detection of TXE is set, if the Txe, if the position of the TC, if the Txe reset, from the TDR loaded data to the sending shift register, loaded after the end, the position txe. so, in fact, this is not what STM32 the serial port to send the bug, but STM32 provides non-null protection of the sending shift register (the non-null is not said nonzero, record shift counter is not 0), and its execution process is in accordance with the official reference document description. To be said to be a bug, is the STM32 position te, in the process of sending idle frames, the TC should not be placed. SummarizeWhen the sending shift register is sent, the status of the TC is read first, and if the TC is set, the serial port ignores the data in the TDR (this also conforms to the official reference document description, when the TC is set, the Send shift register is empty, the write data to the USART_DR is placed directly into the send shift register, The TDR stored the first data is ignored, which also explains the first data loss problem), if the TC is not set, the detection of TXE is set, if the Txe, if the position of the TC, if the Txe reset, from the TDR loaded data to the sending shift register, loaded after the end, the position txe.
About STM32 USART (serial port) The real reason to send data loss first frame