why is my loop function hanging when it reaches fgets(); - c

I am just trying to toggle on Board LED and listen to incoming Data from the terminal window at the same time, but the whole Loop function hangs when it reachs the fgets(), until I send something the the terminal window then it continues to loop. There must be something like "if Serial available , then start to read ?? Here is my Code, I'm new in Atmel studio
#include <asf.h>
#include <string.h>
char incomingData [256];
// /**
// * \brief Configure UART for debug message output.
// */
static void configure_console(void)
{
const usart_serial_options_t uart_serial_options = {
.baudrate = CONF_UART_BAUDRATE,
#ifdef CONF_UART_CHAR_LENGTH
.charlength = CONF_UART_CHAR_LENGTH,
#endif
.paritytype = CONF_UART_PARITY,
#ifdef CONF_UART_STOP_BITS
.stopbits = CONF_UART_STOP_BITS,
#endif
};
// /* Configure console UART. */
sysclk_enable_peripheral_clock(CONSOLE_UART_ID);
stdio_serial_init(CONF_UART, &uart_serial_options);
}
int main (void)
{
/* Insert system clock initialization code here (sysclk_init()). */
board_init();
sysclk_init();
configure_console();
/* Insert application code here, after the board has been initialized. */
gpio_set_pin_low(LED0_GPIO);
while (1)
{
printf("Hello\r\n");
gpio_toggle_pin(LED0_GPIO);
fgets(incomingData,sizeof(incomingData),stdin);
printf("%s\r\n",incomingData);
}
}

Related

How do I enable the Timer_A0 module for the following CCS IDE MSP432P401R Launchpad microcontroller code?

I have the following code for a task that requires me to use the following code to use the Timer_A0 module in the CCS IDE to control the speeds of the motors for a robot that uses the MSP432P401R launchpad as the control unit. How do I initialize the Timer_A0 module in the C programming code below?:
#include "driverlib.h"
#include "mechrev.h"
/* Define macros and function prototypes if needed */
#define BTN1_PIN GPIO_PORT_P1,GPIO_PIN1
#define BTN2_PIN GPIO_PORT_P1,GPIO_PIN4
#define ENB1_PIN GPIO_PORT_P1,GPIO_PIN6
#define ENB2_PIN GPIO_PORT_P1,GPIO_PIN7
#define PWM1_PIN GPIO_PORT_P2,GPIO_PIN4
#define PWM2_PIN GPIO_PORT_P2,GPIO_PIN5
#define PWM3_PIN GPIO_PORT_P2,GPIO_PIN6
#define PWM4_PIN GPIO_PORT_P2,GPIO_PIN7
#define BMP0_PIN GPIO_PORT_P4,GPIO_PIN0
#define BMP7_PIN GPIO_PORT_P4,GPIO_PIN7
#define BMP2_PIN GPIO_PORT_P4,GPIO_PIN2
#define BMP6_PIN GPIO_PORT_P4,GPIO_PIN6
#define BMP3_PIN GPIO_PORT_P4,GPIO_PIN3
#define BMP5_PIN GPIO_PORT_P4,GPIO_PIN5
#define BTN3_PIN GPIO_PORT_P4, GPIO_PIN0 | GPIO_PIN7
#define BTN4_PIN GPIO_PORT_P4, GPIO_PIN2 | GPIO_PIN6
#define BTN5_PIN GPIO_PORT_P4, GPIO_PIN3 | GPIO_PIN5
/* Define configuration structs if needed */
/* Declare global variables if needed */
int i = 0;
uint32_t counter = 0;
/* Main program */
void main(void)
{
/* Stop Watchdog Timer */
WDT_A_holdTimer();
/* Call the mechrev_setup function included in the mechrev.h header file */
mechrev_setup();
/* Initialize GPIOs P1.1 and P1.4 for PushButtons (S1 and S2 switches) */
MAP_GPIO_setAsInputPinWithPullUpResistor(BTN1_PIN);
MAP_GPIO_setAsInputPinWithPullUpResistor(BTN2_PIN);
/* Initialize GPIOs P1.6 and P1.7 for Motor Driver IC Enable Pins */
MAP_GPIO_setAsOutputPin(ENB1_PIN);
MAP_GPIO_setAsOutputPin(ENB2_PIN);
/* Initialize GPIOs P2.4, P2.5, P2.6 and P2.7 for PWM functionality */
MAP_GPIO_setAsInputPin(PWM1_PIN);
MAP_GPIO_setAsInputPin(PWM2_PIN);
MAP_GPIO_setAsInputPin(PWM3_PIN);
MAP_GPIO_setAsInputPin(PWM4_PIN);
/* Initialize Timer A0 to generate PWM signals */
(Timer_A0 module needs to be initialized here)
/* Declare local variables if needed */
/* Call the initialization grading macro */
MACRO_LAB4_INIT();
while(1)
{
/* Design a Polling process to detect PushButtons press and adjust the PWM duty cycles
accordingly */
if (MAP_GPIO_getInputPinValue(BTN1_PIN) == GPIO_INPUT_PIN_LOW)
{
if(i == 1)
{
TA0CCR1 = 999;
TA0CCR2 = 0;
TA0CCR3 = 999;
TA0CCR4 = 0;
}
if(i == 2)
{
TA0CCR1 = 1998;
TA0CCR2 = 0;
TA0CCR3 = 1998;
TA0CCR4 = 0;
}
if(i == 3)
{
TA0CCR1 = 3000;
TA0CCR2 = 0;
TA0CCR3 = 3000;
TA0CCR4 = 0;
}
for (i=0; i<10000; i++); // switch debouncing
}
else if (MAP_GPIO_getInputPinValue(BTN2_PIN) == GPIO_INPUT_PIN_LOW)
{
if(i == 1)
{
TA0CCR1 = 0;
TA0CCR2 = 999;
TA0CCR3 = 0;
TA0CCR4 = 999;
}
if(i == 2)
{
TA0CCR1 = 0;
TA0CCR2 = 1998;
TA0CCR3 = 0;
TA0CCR4 = 1998;
}
if(i == 3)
{
TA0CCR1 = 0;
TA0CCR2 = 3000;
TA0CCR3 = 0;
TA0CCR4 = 3000;
}
for (i=0; i<10000; i++); // switch debouncing
}
else
{
TA0CCR1 = 0;
TA0CCR2 = 0;
TA0CCR3 = 0;
TA0CCR4 = 0;
}
/* Note: Call the event grading macro after changing PWMs */
MACRO_LAB4_EVENT();
}
}
void PORT4_IRQHandler(void)
{
/* Check the interrupt status */
uint32_t status;
status = MAP_GPIO_getEnabledInterruptStatus(GPIO_PORT_P4);
if (status)
{
if(MAP_GPIO_getInputPinValue(BMP0_PIN) == GPIO_INPUT_PIN_LOW ||
MAP_GPIO_getInputPinValue(BMP7_PIN) == GPIO_INPUT_PIN_LOW)
{
i = 1;
counter++;
}
else if (MAP_GPIO_getInputPinValue(BMP2_PIN) == GPIO_INPUT_PIN_LOW ||
MAP_GPIO_getInputPinValue(BMP6_PIN) == GPIO_INPUT_PIN_LOW)
{
i = 2;
counter++;
}
else if (MAP_GPIO_getInputPinValue(BMP3_PIN) == GPIO_INPUT_PIN_LOW ||
MAP_GPIO_getInputPinValue(BMP5_PIN) == GPIO_INPUT_PIN_LOW)
{
i = 3;
counter++;
}
}
else
{
counter++;
}
MACRO_LAB3_EVENT();
/* Clear the PORT4 interrupt flag */
MAP_GPIO_clearInterruptFlag(GPIO_PORT_P4, status);
}
Before you can configure the timer itself, you need to initialize a struct that you will use to configure the timer (there are slight differences in the values needed for upmode, updownmode, continuous mode). You can download the Driverlib Manual MSP432 DriverLib for MSP432 devices which contains detailed use of the timers.
Another very helpful tutorial is Interrupts, Timers & Debugging
You are mixing both Driverlib names and register-level names in your code. That's fine, just make sure you keep the nomenclature straight and don't confuse register access names with user variables, etc..
Now, to configure your timer Timer_A0, you need to initialize a structure to use configuring the time. An example for configuring the timer in up mode would be:
/* TimerA0 UpMode Configuration Parameter */
const Timer_A_UpModeConfig upConfigTA0 =
{
TIMER_A_CLOCKSOURCE_ACLK, /* ACLK Clock 32 KHz (uint_fast16_t clockSource) */
TIMER_A_CLOCKSOURCE_DIVIDER_1, /* Rollover in 1 sec (uint_fast16_t clockSourceDivider) */
ACLKMAX, /* 32767 ticks (uint_fast16_t timerPeriod) */
TIMER_A_TAIE_INTERRUPT_DISABLE, /* Rollover TAIE (uint_fast16_t timerInterruptEnable_TAIE) */
TIMER_A_CCIE_CCR0_INTERRUPT_ENABLE, /* CCR0 CCR0IE (uint_fast16_t captureCompareInterruptEnable_CCR0_CCIE) */
TIMER_A_DO_CLEAR /* Clear Timer (uint_fast16_t timerClear) */
};
Above the timer is configured to use ACLK (32KHz), but you can use SMCLK as well.
Within your code you will need to configure the timer using the struct above. For example:
/* Configuring TimerA0 for Up Mode */
MAP_Timer_A_configureUpMode (TIMER_A0_BASE, &upConfigTA0);
You can also configure/set any additional timer interrupts you plan to use, e.g.
/* Set Capture/Compre Register 3 */
MAP_Timer_A_setCompareValue (TIMER_A0_BASE, MPUCCR, MPUCCRTICKS);
/* enable CCRn compare interrupt */
MAP_Timer_A_enableCaptureCompareInterrupt (TIMER_A0_BASE, MPUCCR);
At this point you have your timer and interrupts configured and read to use, but the timer is not yet started. Before the timer and interrupts are active, you must start the timer itself. Generally, you do this right before you enter you program loop (the while (1) { ... } loop). That way you can configure other peripherals without having your interrupts starting to fire until you complete all your configuration. After everything is configured, start the timer:
/* Starting the Timer_A0 in up mode (just before while loop) */
MAP_Timer_A_startCounter (TIMER_A0_BASE, TIMER_A_UP_MODE);
With every timer, you have two primary interrupt service routines provided by driverlib. The first handles CCR0 and is named TA0_0_IRQHandler() for Timer_A0 (or TA1_0_IRQHandler for Timer_A1, etc..)). It's declaration is:
/**
* Timer A0 CCR0 Interrupt
*/
void TA0_0_IRQHandler(void)
{
...
}
All other interrupts associated with the timer use TA0_N_IRQHandler(). For instance for capture/compare registers CCR1 - CCR5 and the TAIE rollover interrupt (one clock-cycle after CCR0). It has a declaration of
/**
* Timer A0 Interrupt Handler (remaining interrupts)
*/
void TA0_N_IRQHandler(void)
{
...
}
Since you are looking to control a robot arm, I presume you will be using the timer for PWM control. The tutorial covers that fairly well.
I placed complete example using Timer_A to driver PWM on pastebin at MSP432 PWM Control of Tri-Color LED. That shows the use of upmode to drive PWM.
DO NOT OVERLOAD THE INTERRUPT FUNCTIONS WITH FUNCTION CALLS OR COMPUTATIONALLY INTENSIVE CODE. They are effectively signal-handlers. You want to avoid time consuming processing in the ISR (Interrupt Service Request) functions. Instead, the best approach is to set a flag in the interrupt function to complete processing in your program loop, e.g.
/* Starting the Timer_A0 in up mode */
MAP_Timer_A_startCounter (TIMER_A0_BASE, TIMER_A_UP_MODE);
while (1)
{
if (btn1pressed) { /* respond to button presses by calling button handlers */
btn1_handler();
}
if (btn2pressed) {
btn2_handler();
}
if (getmpudata) { /* retrieve data from MPU9250 */
get_MPU_data();
}
if (getmagdata) { /* retrieve data from AK8963 */
get_MAG_data();
}
...
Above, each of the variable names contained in the if (...) statements are simply bool variables set in the interrupt functions that tell your program it's time to process whatever function they trigger. Processing is done in main() not in the interrupt functions. The reason being that heavy computation in the interrupt function can cause the interrupt to fire again before your processing is complete (your code takes more time than the time between interrupts). That is a sure-fire way to cause your program to crater.
The driverlib user's guide is a goldmine for configuring all the peripherals. See if you can get your timer working and look at the tutorial link I provided above. Let me know if you have further questions.

Problems with code to send request and receive response over UART on Atmel SAM L21 Xplained Pro

I'm currently developing a system which involves sending a request string to a sensor device connected via UART to an Atmel SAML21 Xplained Pro board. I'm testing with an Arduino board as the "sensor device", but eventually, it'll be for a Rotronic HC-2 sensor.
The process goes something like this:
MCU sends string { 99RDD} over UART to sensor
-> delay of up to 500ms
-> Response string of 99 bytes sent back via UART
-> Response transmitted to virtual com port on embedded debugger
My issue is that for some reason, I'm either not getting anything sent back, or it's sending back the variable request_msg
I know that the response from the sensor should be 99 bytes of ASCII, and I've tested both the actual sensor, and the Arduino test board over serial connectors to ensure that the readings are coming back correctly.
The software is using Atmel ASF v4.0, which is great when it works, but the documentation is fairly flaky, so I was hoping someone with more experience could point me as to where I'm going wrong in the code.
I have the following code for my main application:
#include "atmel_start.h"
#include "atmel_start_pins.h"
#include <string.h>
static uint8_t example_hello_world[14] = "Hello World!\n";
static uint8_t example_error_msg[13] = "UART Error!\n";
static uint8_t request_msg[24] = "Sending Sensor Request\n";
static uint8_t rotronic_ascii[8] = "{ 99RDD}";
volatile static uint32_t data_arrived = 0;
volatile static uint32_t reading_received = 0;
static void tx_cb_EDBG_COM(const struct usart_async_descriptor *const io_descr)
{
/* Transfer completed */
gpio_toggle_pin_level(LED0);
}
static void rx_cb_EDBG_COM(const struct usart_async_descriptor *const io_descr)
{
/* Receive completed */
data_arrived = 1;
}
static void err_cb_EDBG_COM(const struct usart_async_descriptor *const io_descr)
{
/* error handle */
io_write(&EDBG_COM.io, example_error_msg, 13);
}
static void tx_cb_COM1(const struct usart_async_descriptor *const io_descr)
{
/* Transfer completed */
gpio_toggle_pin_level(LED0);
}
static void rx_cb_COM1(const struct usart_async_descriptor *const io_descr)
{
/* Receive completed */
reading_received = 1;
}
static void err_cb_COM1(const struct usart_async_descriptor *const io_descr)
{
/* error handle */
io_write(&COM1.io, example_error_msg, 13);
}
int main(void)
{
volatile uint8_t recv_char[99];
atmel_start_init();
// Setup the EDBG Serial Port
usart_async_register_callback(&EDBG_COM, USART_ASYNC_TXC_CB, tx_cb_EDBG_COM);
usart_async_register_callback(&EDBG_COM, USART_ASYNC_RXC_CB, rx_cb_EDBG_COM);
usart_async_register_callback(&EDBG_COM, USART_ASYNC_ERROR_CB, err_cb_EDBG_COM);
usart_async_enable(&EDBG_COM);
// Send a test string to ensure EDBG Serial is working
io_write(&EDBG_COM.io, example_hello_world, 14);
// Setup the Rotronic [Arduino] Serial Port
usart_async_register_callback(&COM1, USART_ASYNC_TXC_CB, tx_cb_COM1);
usart_async_register_callback(&COM1, USART_ASYNC_RXC_CB, rx_cb_COM1);
usart_async_register_callback(&COM1, USART_ASYNC_ERROR_CB, err_cb_COM1);
usart_async_enable(&COM1);
while (1) {
if (reading_received == 0)
{
// Delay for a Bit
delay_ms(5000);
// Notify the EDBG COM Port
io_write(&EDBG_COM.io, request_msg, 24);
// Send the Rotronic ASCII
io_write(&COM1.io, rotronic_ascii, 8);
}
// Check if Reading has been Received
if (reading_received == 1)
{
while (io_read(&COM1.io, &recv_char, 99) == 99)
{
// Write what's on the buffer from the receiver
io_write(&EDBG_COM.io, recv_char, 99);
}
// Reset the flag
reading_received = 0;
}
}
}
You seem to be coding for ASFv3 - v4 will trigger your receive callback for any incoming bytes, not only once when your buffer is full (and you have received every 99 characters).
That means that io_read will most probably never return 99 (because it was only a partial read of your message) and you will most probably never send anything back.
Note the docs say (Scroll down to "different read function behavior..."):
In ASFv4 a data reception type callback in a driver with a ring buffer is triggered for every received data.
The UART apparently is a driver with a ring buffer.
You need to repeatedly call io_read and sum up the number of received bytes until you have got 99. Only then proceed. The ASF docs have an example for that. Make sure you copy code from there that fits your version.

RTC on an mcu - function pointers and callbacks

The code below is an example of how to use the real time clock on an mcu.
My question is in relation to callbacks and function pointers.
I have included the struct declaration for rtc_config_t below.
My question is, on the line cfg.callback = rtc_example_callback
Why is the & sign not used before rtc_example_callback.
Why is not necessary to pass the arguments to rtc_example_callback?
The last struct memeber void *callback_data; is set to NULL, I don't understand what this does?
When or what would you want to return?
Many tanks for your inputs
#include "rtc.h"
#include "interrupt.h"
#include "isr.h"
#define ALARM (QM_RTC_ALARM_MINUTE / 6)
#define MAX_RTC_FIRINGS (5)
void rtc_example_callback(void *);
static volatile uint32_t rtc_fired = 0;
/* RTC app example */
int main(void)
{
/* Variables */
rtc_config_t cfg; //create a struct variable to configure the RTC
PRINTF("Starting: RTC\n");
/* Initialise RTC configuration */
cfg.init_val = 0;
cfg.alarm_en = true;
cfg.alarm_val = ALARM;
cfg.callback = rtc_example_callback;
cfg.callback_data = NULL;
irq_request(IRQ_RTC_0, rtc_isr_0); //submit the RTC to the interrupt service routine
clk_periph_enable(CLK_PERIPH_RTC_REGISTER | CLK_PERIPH_CLK); //switch on RTC and Periphal clock
rtc_set_config(RTC_0, &cfg); //Set the RTC configuration
/* Wait for RTC to fire 5 times and then finish. */
while (rtc_fired < MAX_RTC_FIRINGS) {
}
PRINTF("Finished: RTC\n");
clk_periph_disable(CLK_PERIPH_RTC_REGISTER | CLK_PERIPH_CLK); //turn off the clocks
return 0;
}
void rtc_example_callback(void *data)
{
PUTS("Alarm!!\n");
qm_rtc_set_alarm(RTC_0, (RTC[RTC_0].rtc_ccvr + ALARM));
rtc_fired++;
}
-----------------------------------------------------------------------
/**
* RTC configuration type.
*/
typedef struct {
uint32_t init_val; /**< Initial value in RTC clocks. */
bool alarm_en; /**< Alarm enable. */
uint32_t alarm_val; /**< Alarm value in RTC clocks. */
/**
* User callback.
*
* #param[in] data User defined data.
*/
void (*callback)(void *data);
void *callback_data; /**< Callback user data. */
} rtc_config_t;
name of the function is a pointer to the function
function will be called with arguments from rtc library, you are not invoking it (you cannot pass arguments here).
I guess that NULL assigned to custom_callback will not call custom method from library (default function or no function will be called), just assign NULL if you dont want to use custom callback.
usually library code looks like:
if(custom_callback)
{
custom_callback(some_parameters);
}
else
{
default_callback(some_parameters);
}

Interfacing gsm with LPC2148

I am trying to send a message from my ARM7 LPC2148 board. I have connected a SIM900 GSM Modem to the UART0 of the board. But I am not receiving the message on my phone!!I have put print statements here and there so that I know where the system is and where its stuck. But it prints all the messages. It says message sent even though I have not received any SMS.
Here is the code:
Main code
#include "i2c.h"
#include "LPC214x.H" // LPC2148 MPU Register
#include <stdio.h>
#include "gsm.h"
#include "lcd.h"
#include "buzzer.h"
extern int msgflag;
/* Main Program Start Here */
int main(void)
{
PINSEL0 = 0x00000000; // Enable GPIO on all pins
PINSEL1 = 0x00000000;
PINSEL2 = 0x00000000;
lcd_init(); // Initial LCD
lcd_write_control(0x01); // Clear Display (Clear Display,Set DD RAM Address=0)
goto_cursor(0x00); // Set Cursor Line-1
lcd_print("Accident Alert"); // Display LCD Line-1
// Display LCD Line-2
// Display Delay
// Clear Display (Clear Display,Set DD RAM Address=0)
// Display LCD Line-1
goto_cursor(0x40); // Set Cursor = Line-2
lcd_print("System"); // Display LCD Line-2
delay1(100000000);
gsmperform();
// Loop Print Message to LCD16 x 2 //
// Loop Continue
sendmsg();
msgflag=0;
lcd_write_control(0x01); // Clear Display (Clear Display,Set DD RAM Address=0)
goto_cursor(0x00); // Set Cursor Line-1
lcd_print("Message sent"); // Display LCD Line-1
}
gsm.c
#include<lpc214x.h> /*Header file*/
#include "gsm.h"
#include "lcd.h" //header file
extern unsigned char cmgf[]="AT+CMGF=1"; //Text format in GSM modem
extern unsigned char cmgs[]="AT+CMGS=\"9xxxxxxxxx\""; //Mobile number to which the msg is sent
extern unsigned char msg[]="hello"; //secret code
extern unsigned char readall[]="AT+CMGR=\"REC UNREAD\"\r\n";
extern int blink;
unsigned char content[7];
void txu1(unsigned char data) //Transmit a byte of data through UART1
{
while(!(U1LSR & 0x20)); // Wait until UART1 ready to send character
U1THR = data;
}
unsigned char rxu1()
{
unsigned char p;
while ((U1LSR&0x01)!=1);
p=U1RBR;
return p;
}
unsigned char rxu0()
{
unsigned char p;
while ((U0LSR&0x01)!=1);
p=U0RBR;
return p;
}
void sendstring(unsigned char *p) //Sends a string of data through UART1
{
while(1)
{
if(*p=='\0') break;
txu1(*p++);
}
}
void delaygsm() //delay function
{
int i,j;
for(i=0;i<60000;i++)
for(j=0;j<51;j++);
}
void delay2() //delay function
{
int i,j;
for(i=0;i<60000;i++)
for(j=0;j<200;j++);
}
unsigned char recuart1() //recieves a byte from UART1
{
unsigned char p;
while ((U1LSR&0x01)!=1);
p=U1RBR;
return p;
}
void uart1_irq() __irq //ISR if anything is recieved in UART1, the same is transmitted through UART0
{
unsigned char p;
p=U1RBR;
if(p=='a')
{
sendmsg();
}
VICVectAddr=0;
}
void sendmsg(void)
{
sendstring(msg);
}
void initgsm() //Initialization of UART0,UART1 and ISR
{
U0LCR=0x83;
U0DLL=0x61;
U0DLM=0x00;
U0LCR=0x03;
U1LCR=0x83;
U1DLL=0x61;
U1DLM=0x00;
U1LCR=0x03;
U1IER=0x01;
U1FCR=0x07;
VICIntSelect&=0xffffff7f;
VICVectAddr2=(unsigned int)uart1_irq;
VICIntEnable|=0x00000080;
VICVectCntl2=0x20|7;
}
void gsmperform(void)
{
lcd_write_control(0x01); // Clear Display (Clear Display,Set DD RAM Address=0)
goto_cursor(0x00); // Set Cursor Line-1
lcd_print("begin gsm"); // Display LCD Line-1
PINSEL0|=0x00050005;
PINSEL1|=0x00000000;
PINSEL2|=0x00000000;
initgsm();
sendstring("ATe0\r\n");
delaygsm();
sendstring("AT+CMGD=1,4\r\n");
delaygsm();
sendstring("AT+CNMI=1,0,0,0\r\n");
delaygsm();
lcd_write_control(0x01); // Clear Display (Clear Display,Set DD RAM Address=0)
goto_cursor(0x00); // Set Cursor Line-1
lcd_print("end gsm"); // Display LCD Line-1
}
Break up the problem into three parts - Configuring & sending the command, receiving the correct command, and working together.
Connect your LPC2148 board to a PC, and use a PC terminal program to watch what commands you are sending. Make sure the parts of your program is working correctly. Are you running any optimizing options in your compiler? That will mess up your delay functions for sure. Use a built-in timer to provide the delay, not for loops.
Make sure you are using the correct commands to talk to the GSM card. Connect it to a PC if possible (make sure you convert from logic levels to UART levels if it does not have an RS-232 transceiver on it), or to a kit running an interactive terminal. Make sure your commands actually will send an SMS message with the module you have chosen.
Now connect the kit and the module. By now you should know which signals are actually outputs and which are inputs - RS-232 can be very confusing about this. Most processor UARTs are labelled as DTE (TX==output, RX==input), and I'd expect the comms module labeled as DCE (TX==input, RX==output), which means that you would connect RX<->RX and TX<->TX. If they are both labeled as DTE, then you need a null-modem cable to swap the signals, or do it by hand when attaching the board.

AVR Hyperterminal not displaying sensor values

I need to read values form a distance sensor in volts. The sensor sends the voltages binary values to the MUC (Atmega8) and then the atmega8 communicates to my pc using USART with and RS232 cable. The readings displayed on the PC are weird random characters. I don't understand what am I doing wrong.
Here is my code
//USART communicating with Atmega8
#include <avr/io.h>
#include <inttypes.h>
#include <util/delay.h>
#include <string.h>
//1MHZ Baud 9600
#define F_CPU 1000000
char *Bestbelieve ="t \r\n";
void InitADC()
{
ADMUX=(0<<REFS1)|(1<<REFS1); // For Aref=internal;
ADCSRA=(1<<ADEN)|(0<<ADPS2)|(1<<ADPS1)|(1<<ADPS0); //Prescalar div factor =8
}
uint16_t ReadADC()
{
ADMUX=0x05;
//Start Single conversion
ADCSRA|=(1<<ADSC);
//Wait for conversion to complete
while(!(ADCSRA & (1<<ADIF)));
//Clear ADIF by writing one to it
//Note you may be wondering why we have write one to clear it
//This is standard way of clearing bits in io as said in datasheets.
//The code writes '1' but it result in setting bit to '0' !!!
ADCSRA|=(1<<ADIF);
return(ADC);
}
void Wait()
{
uint8_t i;
for(i=0;i<20;i++)
_delay_loop_2(0);
}
char USARTReadChar()
{
//Wait until a data is available
while(!(UCSRA & (1<<RXC)))
{
//Do nothing
}
//Now USART has got data from host
//and is available is buffer
return UDR;
}
void USARTWriteChar(char* data)
{
//Wait until the transmitter is ready
while(*data)
{ while(!(UCSRA & (1<<UDRE)))
{
//Do nothing
}
//Now write the data to USART buffer
UDR=*data;
data++;
}}
void USARTInit(uint16_t ubrr_value)
{
UBRRL = 12;
UBRRH = 0;
UCSRC=(1<<URSEL)|(3<<UCSZ0);
UCSRB=(1<<RXEN)|(1<<TXEN);
UCSRA=(1<<U2X);
}
int main()
{
uint16_t adc_result;
//Initialize ADC
InitADC();
USARTInit(12); //UBRR = 12
//Loop forever
while(1)
{
adc_result=ReadADC(); // Read Analog value from channel-0
char *result[15];
sprintf(result,"%d",adc_result);
Wait();
USARTWriteChar(adc_result);
/* The code continuously has t outputted and skipped lines.
*/
}
}
You are using sprintf to format your data into result. However, you then use USARTWriteChar on your binary value adc_result.
You need to print out result instead, presumably with a loop over the characters calling USARTWriteChar.

Resources