Only receiving "<0><0><0><0><0><0><0>" on USART signal - microcontroller

When I try to receive the USART signal with my Silicon Labs CP210x USB to UART Bridge. The only thing I receive is:
<0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0> etc
I got the right settings selected: baud rate: 9600 data bits: 8 parity: none stop bits: 1
I use a ATmega128A3U. The test_LED (see code below) on port E pin 0 is working. I used a oscilloscope to check the uart signal. See picture here: http://imgur.com/dPxkdZ6
Does someone know a solution for this?
Does anyone know how to fix a framing error? (My UART software is giving this error)
CODE:
#define F_CPU (32000000UL) // CPU clock speed
#include <avr/io.h>
#include <util/delay.h>
void USARTF0_init() {
USARTF0_BAUDCTRLB = 0; //BSCALE is 0
USARTF0_BAUDCTRLA = 0xCF; //BSEL is 207
USARTF0_CTRLA = 0; //Disable interrupts
USARTF0_CTRLC = USART_CHSIZE_8BIT_gc; //8 data bits, no parity and 1 stop bit
USARTF0_CTRLB = USART_TXEN_bm | USART_RXEN_bm; // //Enable receive,transmit and high speed mode
PORTF_OUTSET = PIN3_bm; // Port F pin 3 as TX
PORTF_DIRSET = PIN3_bm; // TX pin as output
PORTF_OUTCLR = PIN2_bm; // Port F pin 2 as RX
PORTF_DIRCLR = PIN2_bm; // RX pin as input
}
void sendChar(char c) {
while( !(USARTF0_STATUS & USART_DREIF_bm) ); //Wait until DATA buffer is empty
USARTF0_DATA = c;
}
void sendString(char *text) {
while(*text) {
sendChar(*text++);
}
}
int main(void) {
USARTF0_init();
PORTE.DIRSET = PIN0_bm; // make port E pin 0 output (test_LED)
while(1)
{
_delay_ms(10);
sendString("Hello World!\n\r");
PORTE.OUTTGL = PIN0_bm; // test_LED Toggle
}
}
Code source: http://morf.lv/modules.php?name=tutorials&lasit=29

To recap the discussion, so it can useful to someone later.
If you have an oscilloscope, capture a trace for a simple test case, as #DrOctorooi has done with "#~00":
He has marked start and stop bits, and also the data bits (for serial/UART they're least-significant first)
This confirms that UART somehow works.
One should also confirm the voltage levels. 0-3.2V looks about right.
And the time base. On the captured trace it appears 1 bit takes 1.625ms, which means a baudrate of around 615. That's quite far from expected 9600. In fact, that's around 16 times slower.
Since the error has to do with time, the immediate questions are the MCU clock and UART clock dividers (and on more complex devices, and intermediate dividers and clocks).
It turns out the dividers were meant for the 32MHz clock, but this MCU has a clock of 2MHz when it comes out of reset (16 times slower, as we have seen above). Solution was to recalculate the dividers.

Related

ESP32 Interrupt jitter at 20kHz

I would like your help to solve the following problem.
I'm using an ESP32 Dev Kit V1 connected as follows:
Pin 4 (input) is connected to a 20kHz and 3.3V signal and to channel 1 of the oscilloscope; and
Pin 2 (output) is connected to channel 2 of the oscilloscope.
My goal is to use interrupts and generate a signal on pin 2 (output) that follows the variations of the signal on pin 4 (input).
The image below illustrates two behaviors. The most frequent and the other one that happens occasionally.
In the first behavior, the latency is around 3 us, but sometimes there is a variation (jitter) and the rise of the output signal takes 15 us or even more to keep up with the input.
I would like to know how to remove this occasional behavior and keep the system stable.
The code that I'm using is below. To compile and upload I am using the latest Arduino IDE version 1.8.13.
I'm using GPIO.out_w1ts and GPIO.out_w1tc because I believe it will be faster than using digitalWrite(pin, state).
Also notice that I'm not reading the state of pin 4 (input) to be faster, because of this, sometimes the output signal gets inverted, but that's not a problem at this point.
#define OUTPUT_PIN 2
#define INPUT_PIN 4
volatile bool state = false;
void IRAM_ATTR interruptFunction() {
if (state)
GPIO.out_w1ts = 0b100;
else
GPIO.out_w1tc = 0b100;
state = !state;
}
void setup() {
pinMode(INPUT_PIN, INPUT);
attachInterrupt(digitalPinToInterrupt(INPUT_PIN), interruptFunction, CHANGE);
gpio_config_t io_conf;
io_conf.mode = GPIO_MODE_OUTPUT;
io_conf.pin_bit_mask = 0b100;
gpio_config(&io_conf);
}
void loop() {
}
The settings used in the Arduino IDE are illustrated in the next image.
Thanks in advance for all the help!

SPI not working on atmega328p

I'm trying to program an atmega328p, but the SPI bus isn't working. It's not sending any data over the bus.
My code is as follows:
#include <asf.h>
#include <stdio.h>
#include <main.h>
int main (void)
{
board_init();
SPI_MasterInit();
DDRD = (1<<DDD5);
while(1)
{
PORTB &= ~(1<<DDB2);
SPI_MasterTransmit(0xAB);
PORTB |= (1<<DDB2);
PORTD ^= (1<<DDD5);
}
}
void SPI_MasterInit(void)
{
/* Set MOSI and SCK output, all others input */
DDRB = (1<<5) || (1<<3) || (1<<2);
/* Enable SPI, Master, set clock rate fck/16 */
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
}
void SPI_MasterTransmit(char cData)
{
/* Start transmission */
SPDR = cData;
/* Wait for transmission complete */
while(!(SPSR & (1<<SPIF)));
}
I'm trying to send some random data over the bus (0xAB) to check if the bus works properly so I can add further code. In the while loop I also set a pin.
On my scope image I see no data being send on the SPI pin MOSI and the CLK pin is also not sending information. PB5 (the pin I'm inverting everytime I try to send data) is working and has a period of about 20 microseconds.
I'm programming the Atmega328p through an Atmel ICE. The programming interface is also through SPI, I read somewhere that this might be an issue. I'm not completely sure.
Does anyone know what might be the problem?
My first guess was not setting SS pin (PB2) as output. It may cause switching to the slave mode almost randomly. But it seems to be set as an output (it's not stated in comments).
But after closer look to this expression, it's obvious it's not set at all:
DDRB = (1<<5) || (1<<3) || (1<<2);
There is a huge difference between logical or || and bitwise or |.

Arduino UNO ADC's ADCH returns a constant value in free running mode

I've stripped everything that I'm sure is not relevant out of my code below. Basically we're inputting a signal through pin A0 and sending samples over serial. It's a relatively simple project but because we want to maximize speed we're trying to avoid using analogRead(). However instead of getting a curve back we get a flatline that doesn't respond to any input, only to the prescaler values.
I've verified all of the register changes and they are all set correctly. If we run the system with the analogRead() code then it works so I know the circuit is working. I can not find any clear information around about why this might be happening. I've played around with the ADMUX channel select to see if maybe I was on the wrong channel but I'm not. Overall I'm very confused by this right now!
// defines for setting and clearing register bits
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
void setup() {
// Opens up the serial port with a baud of 115200
Serial.begin(115200, SERIAL_8E2);
pinMode(A0, INPUT);
digitalWrite(A0, HIGH);
// Enable ADC Completion Interrupt
sbi(ADCSRA,ADIE) ;
sei() ;
// Select the correct pin for the ADC
cbi(ADMUX,MUX3);
cbi(ADMUX,MUX2);
cbi(ADMUX,MUX1);
cbi(ADMUX,MUX0);
// Set the ADC to left adjust so that MSB is in low Byte
sbi(ADMUX,ADLAR) ;
sbi(ADCSRA,ADEN) ;
sbi(ADCSRA,ADSC) ;
}
void loop()
{
}
ISR(ADC_vect)
{
Serial.write(ADCH);
cbi(ADCSRA,ADIF);
sbi(ADCSRA,ADSC);
}
Sorry to thread dig, but i came across some information that may help others. Looks like #UncleO is on the right track there. Since you aren't setting the Prescaler ADPS[2:0], they default to 0 (division factor 2), which i too fast for the ADC to reliably approximate the value (http://www.gammon.com.au/adc):
Note that the datasheet (Table 28-7. ADC Characteristics) mentions that the ADC clock frequency range is 50 kHz to 1000 kHz. Thus (at this CPU clock speed of 16 MHz) the smallest prescaler you are allowed to use is 16, which is born out by testing below.
Prescaler 2
Analog port = 0, average result = 1023
Analog port = 1, average result = 1023
Analog port = 2, average result = 1023
Analog port = 3, average result = 1022
Time taken = 26220
Prescaler 16
Analog port = 0, average result = 1022
Analog port = 1, average result = 672
Analog port = 2, average result = 509
Analog port = 3, average result = 0
Time taken = 73164
The reason why it's working when you use the analogRead function is the prescalar is set to 128 within that library

UART communication PIC16f877A

I've been working on a project which requires communication with my laptop and the microchip Pic 16f877a and the communication is not working properly, but When i put this example on Proteus 8 works just fine.
I don't have RS232(serial port) on my laptop, but i had bought TTL module. I use external oscillator 8MHz on the board and baud rate of 9600 bps.
When i connect with my laptop and i send to the TTL module the A symbol nothing hapens and when i send a couple of times A fast i recieve strange symbol like '?' or '#' back.
Here's the code for the Pic:
char x;
void main(){
TRISB = 0x00;
PORTB = 0x00;
UART1_Init(9600);
delay_ms(10);
while(1){
if(UART1_Data_Ready())
{
x = UART1_Read();
if(x == 'A')
{
PORTB = 0xFF;
UART1_Write(13);
UART1_Write_Text("A");
UART1_Write(13);
}
else
{
PORTB = 0x00;
}
}
x= '\0';
}
}
Can someone help me ? What's the problem ?
Two possibilities as far as I can see (assuming UART1_Init(9600); is a correct library function):
You don't have the Rx pin set up as an input; setting TRIS registers to 0 makes all the pins on that port outputs.
You are using incorrect parity.
Have you set a breakpoint at line
x = UART1_Read();
To see what you actually get in when you send from your terminal program?
Have you looked on youe scope to see what is actually coming in on the Rx pin?
delay_ms(10); is completely unnecessary.
give
SPBRG = 139
Refer this link to set the respective Baud Rate Generator

receiving data from pc to PIC 16F877A with compiler hi-tech

I try to send the data from pc to the pic microcontroller. I am a beginner in PIC.
I send the data from hyperterminal and the data will display in the led in port B of PIC.
I used 10Mhz clock and the connection in 9600 baudrate.
here my uart.h program:
char UART_Init(const long int baudrate)
{
unsigned int x;
x = (_XTAL_FREQ - baudrate*64)/(baudrate*64);
if(x>255)
{
x = (_XTAL_FREQ - baudrate*16)/(baudrate*16);
BRGH = 1;
}
if(x<256)
{
SPBRG = x;
SYNC = 0;
SPEN = 1;
TRISC7 = 1;
TRISC6 = 1;
CREN = 1;
TXEN = 1;
return 1;
}
return 0;
}
char UART_TX_Empty()
{
return TRMT;
}
char UART_Data_Ready()
{
return RCIF;
}
char UART_Read()
{
while(!RCIF);
return RCREG;
}
void UART_Read_Text(char *Output, unsigned int length)
{
int i;
for(int i=0;i<length;i++)
Output[i] = UART_Read();
}
void UART_Write(char data)
{
while(!TRMT);
TXREG = data;
}
void UART_Write_Text(char *text)
{
int i;
for(i=0;text[i]!='\0';i++)
UART_Write(text[i]);
}
and this is my main program:
#include<htc.h>
#include<pic.h>
#define _XTAL_FREQ 10000000 //Clock Frequency
#include "uart.h"
void main()
{
TRISB = 0x00; //PORTB as Output
UART_Init(9600);
do
{
if(UART_Data_Ready())
PORTB = UART_Read();
__delay_ms(1000);
}while(1);
}
in hyperteminal I send data say 10010010 but the led in port B do not respond, are there any error in my program?
You have several steps: initialize UART, initialize LEDs, communicate over UART and setup your PC's UART. Which components have you successfully written and tested? You say you're a beginner, so what is the smallest functional program you have successfully executed on a PIC? I've been working with microcontrollers for years, but I still schedule about a whole day to get a single LED to turn on because it could be a software problem, a hardware problem, a voltage problem, an oscillator problem, a PCB problem or a compiler problem.
Here are the steps I take for microchip bring up:
Go over the oscillator section, the configuration bits section, the watchdog section and the pinout section (looking for VDD and VSS) in the datasheet. These are some of the hardest parts to get right. (A gotcha about the oscillator: just because you can program a chip, doesn't mean the oscillator is working because the programmer provides it's own clock.)
Write the bare-minimum code to turn on a single LED.
Write the bare-minimum code to make the LED blink (just use a for-loop delay for now, timers come later)
Write UART initialization code and transmit a single character, I use captial U because it's pretty in binary. TXREG = 'U';
Connect the UART to a PC and see if the hyperterminal sees the U. If it doesn't, I connect an oscilscope to the lines to make sure that the PIC is transmitting, that the PC transmits when I type characters and that the timing of the edges matches.
Within the PIC code, have the UART echo characters from the terminal. (TXREG = RXREG;), and then type on the hyperterminal and make sure the characters are echoed back.
One more note:
Do not have the PIC perform the SPBRG calculation. PIC16 are 8-bit processors and 10000000 requires 32-bits to store. There might be hiccups with the integer divison. It might not have a bug in it, but there's no need to have the PIC calculate it each time. Calculate it before-hand and hard-code the value.

Resources