2010-09-08 04:08 AM
ST32F103ZE USART not receiving?
2011-05-17 05:06 AM
Hi answerers,
somehow all replies have disappeared? There were about 5 replies but now all gone? Some ST-server error? Henk2011-05-17 05:06 AM
That seems to a lot of replies to be missing for a topic that has been open for 5 hours, and didn't appear to have any responses 2 hours ago.
Suspect you were looking at another painfully similar thread. Post some code so we don't have guess what you ended up with.2011-05-17 05:06 AM
Weird things happening here...or was it because I replied to someone that was not the last post in my thread maybe?
Well anyway. There was a question if I had switched on the APBn clock: I did. Another question of about some signal which is not available on the STM32F103ZE. Another question was if I had poweredup. The only thing I found is that the Alternate Function I/O Clock was not enabled but after enabling it the receiver still does not receive anything. Henk2011-05-17 05:06 AM
The forum is certainly a hunk-of-junk, and has eaten a fair amount of my posts.
AFIO only becomes critical if you start remapping peripherals. USART2 is on a different peripheral bus than USART1, but USART1,2,3 all work quite fine. Clocks need to be running to peripherals before you configure them. Once the peripherals are configured, you can enable the peripherals. The sequence of things can be important. Please attach your code if you want someone to review it. Note tool chain you are using.2011-05-17 05:06 AM
Hi,
I think I must apologize, I'm getting old, posting also on the forum busy answering my browser collapsed, I had a meeting and afterwards I logged in on and found my postings were gone... ;) But anyway after 8 hours of puzzling my receiver still does not work. I think indeed it must be something with the initialisaton sequence. I rewrote my code from ASAURT2 to USART1: [code]//include all general system header file (clock divider e.t.c.)
#include <stm32f10x.h>//============================================================
// USART1 IRQ HANDLER //============================================================ void USART1_IRQHandler(void){ //put test pattern on board leds GPIOB->ODR=0x00005500; //disable USART1 global interrupt NVIC->ISER[1]|=~NVIC_ISER_SETENA_5; //wait here for(;;){} }//event//============================================================
// MAIN //============================================================ int main(void){//enable the GPIO clock for port GPIOA
RCC->APB2ENR|=RCC_APB2ENR_IOPAEN;//enable the GPIO clock for port GPIOB
RCC->APB2ENR|=RCC_APB2ENR_IOPBEN;//put test pattern on onboard leds
GPIOB->ODR=0x00005a00;//------------------------------
// AHB prescaler clock setting //------------------------------ //set the AHB prescaler divisor to 1 (so input frequency = 8.000.000 / 1 = 8.000.000Hz) RCC->CFGR=(RCC->CFGR&~RCC_CFGR_HPRE)|RCC_CFGR_HPRE_DIV1;//------------------------------
// APB1 prescaler clock setting //------------------------------ //set the ABP1 prescaler for timers divisor to 8 (so input frequency = 8.000.000 / 8 = 1.000.000Hz) RCC->CFGR=(RCC->CFGR&~RCC_CFGR_PPRE1)|RCC_CFGR_PPRE1_DIV1;//------------------------------
// APB2 prescaler clock setting //------------------------------ //set the ABP2 prescaler for timers divisor to 8 (so input frequency = 8.000.000 / 8 = 1.000.000Hz) RCC->CFGR=(RCC->CFGR&~RCC_CFGR_PPRE2)|RCC_CFGR_PPRE2_DIV1;//------------------------------
// Experiment to reset USART1 //------------------------------ //reset usart1 RCC->APB2RSTR|=RCC_APB2RSTR_USART1RST; //unreset usart1 RCC->APB2RSTR&=~RCC_APB2RSTR_USART1RST;//------------------------------
// USART1 peripheral clock enable //------------------------------ //enable the USART1 peripheral clock RCC->APB2ENR|=RCC_APB2ENR_USART1EN;//------------------------------
// Alternate function io enable //------------------------------ //alternate function io enable RCC->APB2ENR|=RCC_APB2ENR_AFIOEN;//------------------------------
// PA09 (TX) is Alternate Output Push Pull + PA10 (RX) input float //------------------------------ //PA09 is Alternate Output Push Pull + PA10 input float GPIOA->CRH=0x000004b0;//------------------------------
// numbered settings are according reference manual pdf //------------------------------ // 1. Enable the USART by writing the UE bit in USART_CR1 register to 1. USART1->CR1|=USART_CR1_UE;// 2. Program the M bit in USART_CR1 to define the word length.(bit is 0 => 8bits)
USART1->CR1&=~USART_CR1_M;// 3. Program the number of stop bits in USART_CR2. (both bits are 0 => 1 stopbit)
USART1->CR2=(USART1->CR2&~USART_CR2_STOP)|(~USART_CR2_STOP_1&~USART_CR2_STOP_0);// 4. Select DMA enable (DMAR) in USART_CR3 if multibuffer communication is to take
// place. Configure the DMA register as explained in multibuffer communication. STEP 3// 5. Select the desired baud rate using the baud rate register USART_BRR (115200 baud)
USART1->BRR=8000000/115200;// 6. Set the RE bit USART_CR1. This enables the receiver which begins searching for a
// start bit. USART1->CR1|=USART_CR1_RE;//enable receive-data interrupt
USART1->CR1|=USART_CR1_RXNEIE;//----------------------------------------
// to enable the USART1 interrupt // the corresponding bit must be set // in the ISER register//enable USART1 global interrupt
NVIC->ISER[1]=NVIC_ISER_SETENA_5;//debug test: force a pending usart1 interrupt
//NVIC->ISPR[1]=NVIC_ISPR_SETPEND_5;//forever do...
for(;;){ //read and show the status register vShowByteXByOnboardLeds(USART1->SR&0x000000ff);}//for
}//main
[/code] Ahum, there's no preview option on this forum I think so I just paste my code here. Henk2011-05-17 05:06 AM
#include ''stm32f10x.h''
int main(void) { // At Reset STM32 runs off 8 MHz HSI, prescalers are 1, ie all clocks @ 8 MHz //------------------------------ // AHB prescaler clock setting //------------------------------ //set the AHB prescaler divisor to 1 (so input frequency = 8.000.000 / 1 = 8.000.000Hz) RCC->CFGR=(RCC->CFGR&~RCC_CFGR_HPRE)|RCC_CFGR_HPRE_DIV1; //------------------------------ // APB1 prescaler clock setting //------------------------------ //set the ABP1 prescaler for timers divisor to 8 (so input frequency = 8.000.000 / 8 = 1.000.000Hz) RCC->CFGR=(RCC->CFGR&~RCC_CFGR_PPRE1)|RCC_CFGR_PPRE1_DIV1; //------------------------------ // APB2 prescaler clock setting //------------------------------ //set the ABP2 prescaler for timers divisor to 8 (so input frequency = 8.000.000 / 8 = 1.000.000Hz) RCC->CFGR=(RCC->CFGR&~RCC_CFGR_PPRE2)|RCC_CFGR_PPRE2_DIV1; // Could consolidate these //enable the GPIO clock for port GPIOA RCC->APB2ENR |= RCC_APB2ENR_IOPAEN; //enable the GPIO clock for port GPIOB RCC->APB2ENR |= RCC_APB2ENR_IOPBEN; //alternate function io enable RCC->APB2ENR |= RCC_APB2ENR_AFIOEN; //enable the USART1 peripheral clock RCC->APB2ENR |= RCC_APB2ENR_USART1EN; //------------------------------ // PA09 (TX) is Alternate Output Push Pull + PA10 (RX) input float //------------------------------ //PA09 is Alternate Output Push Pull + PA10 input float GPIOA->CRH = (GPIOA->CRH & 0xFFFFF00F) | 0x000004B0; // Set up GPIOB Bits PB.8 thru 15 push-pull 2 MHz, Default to input floating GPIOB->CRH = 0x22222222; //put test pattern on onboard leds GPIOB->ODR = 0x00005A00; //------------------------------ // Experiment to reset USART1 //------------------------------ //reset usart1 RCC->APB2RSTR |= RCC_APB2RSTR_USART1RST; //unreset usart1 RCC->APB2RSTR &= ~RCC_APB2RSTR_USART1RST; // I would program CR1,CR2 and BRR in three single operations // USART1->BRR = 8000000/115200; // USART1->CR1 = 0x200C; // Enable USART,TX,RX // USART1->CR2 = 0x0000; // 115200 8-N-1 //------------------------------ // numbered settings are according reference manual pdf //------------------------------ // 1. Enable the USART by writing the UE bit in USART_CR1 register to 1. USART1->CR1 |= USART_CR1_UE; // 2. Program the M bit in USART_CR1 to define the word length.(bit is 0 => 8bits) USART1->CR1 &= ~USART_CR1_M; // 3. Program the number of stop bits in USART_CR2. (both bits are 0 => 1 stopbit) USART1->CR2 &= ~USART_CR2_STOP; // 4. Select DMA enable (DMAR) in USART_CR3 if multibuffer communication is to take // place. Configure the DMA register as explained in multibuffer communication. STEP 3 // 5. Select the desired baud rate using the baud rate register USART_BRR (115200 baud) USART1->BRR = 8000000/115200; // 6. Set the RE bit USART_CR1. This enables the receiver which begins searching for a // start bit. USART1->CR1 |= USART_CR1_RE; // Simple Rx loop to GPIOB / LEDS while(1) { if (USART1->SR & 0x20) // RXF GPIOB->ODR = (USART1->DR & 0xFF) << 8; } }2011-05-17 05:06 AM
The following lines have issues (don't do what you say they should)
//disable USART1 global interrupt NVIC->ISER[1]|=~NVIC_ISER_SETENA_5; // 3. Program the number of stop bits in USART_CR2. (both bits are 0 => 1 stopbit) USART1->CR2=(USART1->CR2&~USART_CR2_STOP)|(~USART_CR2_STOP_1&~USART_CR2_STOP_0); There are some other ordering issues, I'm cleaning up now, and it doesn't initialize GPIOB for output. Step One, try doing this without interrupts. I use the ST Library to initialize the NVIC, I'm not convinced you have enough code to initialize it properly (ie address grouping, priority, etc).2011-05-17 05:06 AM
For an interrupt, the following example also works.
#include ''stm32f10x.h'' void USART1_IRQHandler(void) { if (USART1->SR & 0x20) // RXF { int i; i = USART1->DR & 0xFF; // Read and clear pending RX IRQ GPIOB->ODR = i << 8; // Led USART1->DR = i; // Echo } } int main(void) { // At Reset STM32 runs off 8 MHz HSI, prescalers are 1, ie all clocks @ 8 MHz //------------------------------ // AHB prescaler clock setting //------------------------------ //set the AHB prescaler divisor to 1 (so input frequency = 8.000.000 / 1 = 8.000.000Hz) RCC->CFGR=(RCC->CFGR&~RCC_CFGR_HPRE)|RCC_CFGR_HPRE_DIV1; //------------------------------ // APB1 prescaler clock setting //------------------------------ //set the ABP1 prescaler for timers divisor to 8 (so input frequency = 8.000.000 / 8 = 1.000.000Hz) RCC->CFGR=(RCC->CFGR&~RCC_CFGR_PPRE1)|RCC_CFGR_PPRE1_DIV1; //------------------------------ // APB2 prescaler clock setting //------------------------------ //set the ABP2 prescaler for timers divisor to 8 (so input frequency = 8.000.000 / 8 = 1.000.000Hz) RCC->CFGR=(RCC->CFGR&~RCC_CFGR_PPRE2)|RCC_CFGR_PPRE2_DIV1; // Could consolidate these //enable the GPIO clock for port GPIOA RCC->APB2ENR |= RCC_APB2ENR_IOPAEN; //enable the GPIO clock for port GPIOB RCC->APB2ENR |= RCC_APB2ENR_IOPBEN; //alternate function io enable RCC->APB2ENR |= RCC_APB2ENR_AFIOEN; //enable the USART1 peripheral clock RCC->APB2ENR |= RCC_APB2ENR_USART1EN; //------------------------------ // PA09 (TX) is Alternate Output Push Pull + PA10 (RX) input float //------------------------------ //PA09 is Alternate Output Push Pull + PA10 input float GPIOA->CRH = (GPIOA->CRH & 0xFFFFF00F) | 0x000004B0; // Set up GPIOB Bits PB.8 thru 15 push-pull 2 MHz, Default to input floating GPIOB->CRH = 0x22222222; //put test pattern on onboard leds GPIOB->ODR = 0x00005A00; //------------------------------ // Experiment to reset USART1 //------------------------------ //reset usart1 RCC->APB2RSTR |= RCC_APB2RSTR_USART1RST; //unreset usart1 RCC->APB2RSTR &= ~RCC_APB2RSTR_USART1RST; // I would program CR1,CR2 and BRR in three single operations // USART1->BRR = 8000000/115200; // USART1->CR1 = 0x200C; // Enable USART,TX,RX // USART1->CR2 = 0x0000; // 115200 8-N-1 //------------------------------ // numbered settings are according reference manual pdf //------------------------------ // 1. Enable the USART by writing the UE bit in USART_CR1 register to 1. USART1->CR1 |= USART_CR1_UE; // 2. Program the M bit in USART_CR1 to define the word length.(bit is 0 => 8bits) USART1->CR1 &= ~USART_CR1_M; // 3. Program the number of stop bits in USART_CR2. (both bits are 0 => 1 stopbit) USART1->CR2 &= ~USART_CR2_STOP; // 4. Select DMA enable (DMAR) in USART_CR3 if multibuffer communication is to take // place. Configure the DMA register as explained in multibuffer communication. STEP 3 // 5. Select the desired baud rate using the baud rate register USART_BRR (115200 baud) USART1->BRR = 8000000/115200; // 6. Set the RE bit USART_CR1. This enables the receiver which begins searching for a // start bit. USART1->CR1 |= USART_CR1_RE; // enable transmit for echo back USART1->CR1 |= USART_CR1_TE; //enable receive-data interrupt USART1->CR1 |= USART_CR1_RXNEIE; //---------------------------------------- // to enable the USART1 interrupt // the corresponding bit must be set // in the ISER register //enable USART1 global interrupt NVIC->ISER[1] = NVIC_ISER_SETENA_5; while(1); // Forever }2011-05-17 05:06 AM
Hi,
>//disable USART1 global interrupt > NVIC->ISER[1]|=~NVIC_ISER_SETENA_5; You'r right it should be '&=' not '|=' >// 3. Program the number of stop bits in USART_CR2. (both bits are 0 => 1 stopbit) > USART1->CR2=(USART1->CR2&~USART_CR2_STOP) >|(~USART_CR2_STOP_1&~USART_CR2_STOP_0); I thought this was okay although a little expanded: (A) = (USART1->CR2&~USART_CR2_STOP) will clear bits 12 and 13 in a copy of CR2 to make room for eventually setting both bits (B) = (~USART_CR2_STOP_1&~USART_CR2_STOP_0) will also clear bits 12 and 13 (or set one or both if needed) So USART1->CR2=(A) | (B) will clear bits 12 and 13 of CR2 meaning using 1 stopbit. Thanks for reviewing my program, tomorrow being at my company I will give it a try. Henk