KEIL4 where the lpc2148 ADC Interrupts or IRQs wont execute - c

I have configured for the ADC channel AD0.1 of processor LPC 2148, with ISR. But while ADC value changes ISR is not executing. Because of this VICVectAddr contains the value of ISR function. This program is part of learning.
Please find the Code below. It is very help full if anybody has given solution
#include <lpc214x.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#define SBIT_RESULT 6u
#define SBIT_CLCKDIV 8u
#define SBIT_BURST 16u
#define SBIT_START 24u
#define SBIT_PDN 21u
#define SBIT_EDGE 27u
#define SBIT_DONE 31u
void ADC_Init (void);
__irq void ADC_ISR (void) ;
void main(void) {
AD0CR=0x0;
ADC_Init ();
while(1){
}
}
void ADC_Init (void)
{
PINSEL1 = 0x01000000 ; // ADC P0.28, AD0.1
AD0INTEN =0x02; //On completetion of ADC channel 1 generate interupt
VICVectAddr5 = (unsigned int)ADC_ISR; // address of the ISR
VICVectCntl5 = (1<<5) | 18;
VICIntSelect &= ~ (1<<18);
VICIntEnable = (1<<18);
AD0CR = 0X00200D02;
AD0CR |= 0x01000000;
}
// Interrupt Service Routine-ISR
__irq void ADC_ISR(void) {
static int flag=0 ;
int val;
unsigned int data;
bool readStatus;
data = AD0GDR ;
readStatus = data & 0x80000000;
if(readStatus){
val = data >>=6;
val= val & 0x3FF;
val=((val/1023.0)*3.3);
}
Delay(1000000);
AD0INTEN =0x0; //clear ADC interrupt
VICVectAddr = 0;
}
```

Related

How can implement delay function with systick in arm processor and make it work in over flow ,the load register is 32 bit

#include"SYSTICK.h"
volatile u32 DELAY;
void SYS_INIT(){
STCTRL =0x0;
STRELOAD =16000000-1; //time for 1s
STCURRENT=0x0;
STCTRL =0x07;
}
void SYS_DELAY(u32 TIME_S){
DELAY = 0;
while(DELAY > TIME_S);
}
void SysTick_Handler(){
DELAY++;
}
#include "GBIO_INIT.h"
#include "USER_INTERFACE.h"
#include "SYSTICK.h"
#define RCGCGPIO *((unsigned int *) 0x400FE608)
int main(void){
/*Enabling clock for GPIO PORTF*/
RCGCGPIO |= (0x20);
SYS_INIT();
while(1){
GPIO_SetPinDirection(SELECTED_PORT,SELECTED_PIN_Input, GPIO_INPUT);
GPIO_SetPinDigEnable(SELECTED_PORT,SELECTED_PIN_Input, GPIO_DEN_SET);
GPIO_SetPinCurrent(SELECTED_PORT,SELECTED_PIN_Input, PORT_BIN_CUR_2MA);
GPIO_SetPinInternalAttach(SELECTED_PORT,SELECTED_PIN_Input, PORT_BIN_PUR);
u8 x =GBIO_ReadPinValeu(SELECTED_PORT,SELECTED_PIN_Input);
GPIO_SetPinDirection(SELECTED_PORT,SELECTED_PIN_OUTPUT,GPIO_OUTPUT);
GPIO_SetPinValue(SELECTED_PORT,SELECTED_PIN_OUTPUT, x);
SYS_DELAY(3);
GPIO_SetPinValue(SELECTED_PORT,SELECTED_PIN_OUTPUT, STD_LOW);
SYS_DELAY(5);
}
}

uart between atmega328p (C) and Feather m0 (Arduino) receive

I want to send data from my ac/gy via atmega328p to a feather m0 module. The atmega is programmed in C using the following github code: https://github.com/YifanJiangPolyU/MPU6050
And the Arduino code for receiving data within the LoRa module is shown below:
void do_send(osjob_t* j){
// Check if there is not a current TX/RX job running
if (LMIC.opmode & OP_TXRXPEND) {
Serial.println(F("OP_TXRXPEND, not sending"));
} else {
// Prepare upstream data transmission at the next possible time.
byte strArray[30];
int i = 0;
if(Serial1.available()>0) {
while (Serial1.available()>0){
strArray[i] = Serial1.read();
i++;
}
// send the 6 bytes payload to LoRaWAN port 7 --> now port 1
LMIC_setTxData2(1, strArray, sizeof(strArray), 1);
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on by making the voltage HIGH //optional: for confirmation
}
}
}
// Next TX is scheduled after TX_COMPLETE event.
//delay(60000);
void loop() {
os_runloop_once();
}
However, I can't seem to receive anything and can't send a "char array" to the gateway using the LMIC function apparently, so trying to receiving data within a byte array instead. Any help or tips regarding this is greatly appreciated. I'll also include the main.c code for the atmega328P down here below:
#define F_CPU 16000000UL
#define BAUD 9600
#include <inttypes.h>
#include <avr/sfr_defs.h>
#include <stdint.h>
#include <avr/io.h>
#include <util/delay.h>
#include <util/setbaud.h>
#include <avr/interrupt.h>
#include <math.h>
#include "mpu6050.h"
#include "mpu6050_reg.h"
#include "i2c.h"
#include "uart.h"
void timer_setup();
void get_time(double* dt);
volatile double count;
const double unit_t = 8/16000000;
int main(void){
sei();
uart_init();
i2c_init();
DDRB |= _BV(5);
uint8_t ret;
int16_t accel_buff[3], gyro_buff[3];
double accelX, accelY, accelZ;
double gyroX, gyroY, gyroZ;
double biasX, biasY;
double phi_accel, theta_accel;
double phi_innov, theta_innov;
double phi_est, theta_est;
double phi_prev, theta_prev;
double dt;
char s[30];
// initialize & test MPU5060 availability
ret = i2c_start(MPU6050_ADDRESS+I2C_WRITE);
if(~ret){
PORTB |= _BV(5);
_delay_ms(200);
PORTB &= ~(_BV(5));
}
mpu6050_init();
timer_setup();
// find gyro bias
biasX = 0;
biasY = 0;
uint8_t i;
for(i=0; i<20; i++){
mpu6050_read_gyro_ALL(gyro_buff);
biasX += gyro_buff[0];
biasY += gyro_buff[1];
}
biasX = biasX/20*(3.14159/180)/1000/32768;
biasY = biasY/20*(3.14159/180)/1000/32768;
// initialization for Kalman filter
double P = 0.0;
double Q = 0.001;
double R = 0.03;
double Pp, K;
mpu6050_read_accel_ALL(accel_buff);
phi_prev = atan2(accelY, accelZ); // row
theta_prev = atan2(-accelX, sqrt(accelY*accelY+accelZ*accelZ)); // pitch
for(;;){
get_time(&dt);
mpu6050_read_accel_ALL(accel_buff);
mpu6050_read_gyro_ALL(gyro_buff);
// acceleration (m/s^2)
accelX = accel_buff[0]*9.8*2/32768;
accelY = accel_buff[1]*9.8*2/32768;
accelZ = accel_buff[2]*9.8*2/32768;
// gyro rate (rad/s)
gyroX = gyro_buff[0]*(3.14159/180)/1000/32768;
gyroY = gyro_buff[1]*(3.14159/180)/1000/32768;
gyroZ = gyro_buff[2]*(3.14159/180)/1000/32768;
// estimation
phi_est = phi_prev + dt*(gyroX - biasX);
theta_est = theta_prev + dt*(gyroY - biasY);
Pp = P+Q;
// innovation
phi_accel = atan2(accelY, accelZ); // row
phi_innov = phi_accel - phi_est;
theta_accel = atan2(-accelX, sqrt(accelY*accelY+accelZ*accelZ)); // pitch
theta_innov = theta_accel - theta_est;
// Kalman gain
K = Pp/(Pp+R);
// correction
phi_prev = phi_prev + K*phi_innov;
theta_prev = theta_prev + K*theta_innov;
P = (1-K)*Pp;
uart_putchar('\n');
_delay_ms(10);
uart_putdouble(phi_prev); //phi, row
uart_putdouble(theta_prev); //theta, pitch
uart_putdouble(dt);
//_delay_ms(10);
}
}//end of main
void timer_setup(){
TCCR1A = 0x00;
TIMSK1 |= _BV(TOIE1);
TCCR1B |= _BV(CS11);
TCCR1B &= ~( _BV(CS12) | _BV(CS10)); // prescaler=8
}
void get_time(double * dt){
cli();
uint8_t l = TCNT1L;
uint8_t h = TCNT1H;
uint16_t step = h<<8 | l;
*dt = (double)step*5e-7 + count*0.032768;
count = 0;
sei();
}
// timer 1 overflow interrupt handler
SIGNAL(TIMER1_OVF_vect){
count += 1;
}
Connect the board to the PC and check in the Arduino IDE Serial Monitor if you can get or send data.
If your serial communication doesn't work, you can check if you are past a point in execution by turning on the led on the board. Most development boards have at least 1, and with Arduino is just a matter of setting the pin as output and digitalWrite(LED_BUILTIN, 0) in setup, then digitalWrite(LED_BUILTIN, 1) at the point you want to check.
If your atmega328p is on an arduino board (e.g. uno, nano etc) you should check in the same way for it, too. Both the serial and past-the-point verification.
I'd to that, then rely on the serial for debugging for a while.
I'm curious, do you think the condition "if(Serial1.available()>0)" is true?

USART with ATMEGA168A -

I am trying to make a very simple USART program which send the received character back to the transmitter and represent the equivalent binary number by flashing 8 leds in my breadboard.
Here is the code:
#define F_CPU 1000000UL // set the CPU clock
#define BAUD 9600 // define baud
#define BAUDRATE ((F_CPU)/(BAUD*16UL)-1) // set baudrate value for UBRR
#include <avr/io.h>
#include <util/delay.h>
#include <stdlib.h>
#include <inttypes.h>
#include "led.h"
// function to initialize UART
void uart_init (void)
{
UBRRH=(BAUDRATE>>8);
UBRRL=BAUDRATE; //set baud rate
UCSRB|=(1<<TXEN)|(1<<RXEN); //enable receiver and transmitter
UCSRC|=(1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1);// 8bit data format
}
// function to send data
void uart_transmit (unsigned char data)
{
while (!( UCSRA & (1<<UDRE))); // wait while register is free
UDR = data; // load data in the register
}
// function to receive data
unsigned char uart_receive (void)
{
while(!(UCSRA) & (1<<RXC)); // wait while data is being received
return UDR; // return 8-bit data
}
// main function: entry point of program
int main (void)
{
unsigned char a = 0;
char buffer[10] = 0;
DDRB = 0xFF;
uart_init(); // initialize UART
while(1)
{
a=uart_receive(); // save the received data in a variable
uart_transmit(a); // send it back
blink(a - 0); // print in the led
_delay_ms(100); // wait before next attempt
}
return 0;
}
The problem I am facing is that none of the registers related to the USART seem to be recognized by the compiler. See an example of the compilation error I am getting:
'UBRRH' undeclared (first use in this function)
Am I missing an include here?
It seems that code you have is not for ATMEGA168, the errors you are getting are due to some registers that doesnt exist in ATMEGA168. In ATMEGA168, there is more than one UART, so the register names are numbered. You can use UBRR0H instead of UBRRH, for example.
Try this:
#ifdef UDR0
#define UBRRH UBRR0H
#define UBRRL UBRR0L
#define UDR UDR0
#define UCSRA UCSR0A
#define UDRE UDRE0
#define RXC RXC0
#define UCSRB UCSR0B
#define RXEN RXEN0
#define TXEN TXEN0
#define RXCIE RXCIE0
#define UCSRC UCSR0C
#define URSEL
#define UCSZ0 UCSZ00
#define UCSZ1 UCSZ01
#define UCSRC_SELECT 0
#else
#define UCSRC_SELECT (1 << URSEL)
#endif
#define BAUD 9600UL
#define UBRRVAL (F_CPU/(BAUD*16)-1)
#define USE_SLEEP 1
void uart_init() {
/* set baud rate */
UBRRH = UBRRVAL >> 8;
UBRRL = UBRRVAL & 0xff;
/* set frame format: 8 bit, no parity, 1 bit */
UCSRC = UCSRC_SELECT | (1 << UCSZ1) | (1 << UCSZ0);
/* enable serial receiver and transmitter */
#if !USE_SLEEP
UCSRB = (1 << RXEN) | (1 << TXEN);
#else
UCSRB = (1 << RXEN) | (1 << TXEN) | (1 << RXCIE);
#endif
}
void uart_putc(uint8_t c) {
if(c == '\n')
uart_putc('\r');
/* wait until transmit buffer is empty */
while(!(UCSRA & (1 << UDRE)));
/* send next byte */
UDR = c;
}
uint8_t uart_getc()
{
/* wait until receive buffer is full */
#if USE_SLEEP
uint8_t sreg = SREG;
sei();
while(!(UCSRA & (1 << RXC)))
sleep_mode();
SREG = sreg;
#else
while(!(UCSRA & (1 << RXC)));
#endif
uint8_t b = UDR;
if(b == '\r')
b = '\n';
return b;
}
int main(){
DDRB = 0xff;
uint8_t data = 0;
uart_init();
while(1){
data = uart_getc();
uart_putc(data);
blink(a - 0);
_delay_ms(100);
}
return 0;
}

AVR, UART, Proteus simulation, not all data displayed on virtual terminal

I am writing a code for a MCU until that will transmit data via UART (RS232).
[ATmega8A]
Currently, I am testing my code in Proteus:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdlib.h>
#include <compat/twi.h>
#define FOSC 16000000 //Clock Speed
#define BAUD 9600 //Baud rate set to 9600
#define MYBRR FOSC/16/BAUD-1
void USART_Init (void)
{
UBRRH = (MYBRR >> 8); //Code for setting
UBRRL = MYBRR; //the baud rate
UCSRB = (1 << RXEN) | (1 << TXEN); //Enable receiver and transmitter
UCSRC = (1 << URSEL) | (1 << UCSZ0) | (1 << UCSZ1); //Frame format setting: 8 Data, 2 Stop bit
}
/* USART transmit function */
void USART_Transmit(unsigned char data)
{
while(!(UCSRA & (1 << UDRE))); //Wait until transmit buffer is empty
UDR = data;
}
/* USART receive function */
unsigned char USART_Receive(void)
{
while(!(UCSRA & (1 << RXC))); //Wait until data is received
return UDR; //Get the data from buffer and return it
}
and the test code in main:
int main(void)
{
unsigned char c;
while(1)
{
a = USART_Receive();
c = 10;
USART_Transmit(c);
_delay(10000);
}
}
In Proteus, the virtual terminal displays 0. However, I am expecting to see 10.
This is just one example, in general only the last digit/character is getting displayed on the virtual terminal.
I cannot explain this. Proteus bug or logic error?
Thank you for any advise.
UART data is sent only in ascii format...you have to convert the integer data to ascii format..use itoa() or do this one
int main(void)
{
unsigned char c;
unsigned char b;
while(1)
{
a = USART_Receive();
c = 10;
b=c;
b=c/10;
USART_Transmit(b+48);
b=0;
b=c%10;
USART_Transmit(b+48);
_delay(10000);
}
}

MSP430 Function Call Being Skipped

I am programming an MSP430 microcontroller with the MSP430 LaunchPad Dev Kit and I am running into some problems on this simple code.
#include <msp430.h>
void Delay(void);
#define LED1 BIT0 //define LED1 as bit 0 (0x00)
#define LED2 BIT6 //define LED2 as bit 6 (0x40)
#define delayTime 20000 //define iTime as 20000
int main(void)
{
WDTCTL = WDTPW | WDTHOLD; //stop watchdog timer
P1DIR |= (LED1|LED2); //set P1.0 and P1.6 to output direction (P1.3 is naturally an input)
P1OUT |= LED1; //set P1.0 high so the LEDs will blink alternatively
while(1)
{
Delay();
P1OUT ^= (LED1|LED2); //toggle P1.0 using exclusive-OR
}
}
void Delay(void)
{
int i = 0;
while(delayTime > i)
{
i++;
}
}
This code compiles fine, but when debugging the code, the function call 'Delay()' is skipped entirely and the function is never entered. However, when I give the function a return type of 'unsigned int' like this:
unsigned int Delay(void)
{
int i = 0;
while(delayTime > i)
{
i++;
}
return 1;
}
I can call the Delay function in an if statement like the one below and the debugger will enter the function.
if(Delay() == 1)
{
P1OUT ^= (LED1|LED2); //toggle P1.0 using exclusive-OR
}
I'm sure there is some simple oversight that I'm making. I can't for the life of me figure out why the debugger is skipping my first void function call. Any wisdom?
swineone has responded with the following correct solution in a comment:
"Try changing the declaration int i = 0; to volatile int i = 0; in the
Delay() function. This tells the optimizer not to touch that variable,
and may be the difference between the optimizer optimizing the code
away or not."
Thanks for the help!
It's recommended to work with interrupts. Such a task goes to this:
#include "io430.h"
#define ON 1
#define OFF 0
#define LED1 P1OUT_bit.P0
#define LED2 P1OUT_bit.P6
void init(void)
{
// Stop watchdog timer to prevent time out reset
WDTCTL = WDTPW + WDTHOLD;
P1OUT = 0x00;
P1DIR = 0xFF;
// initialize Timer0_A
TA0CCR0 = 62500; // set up terminal count
TA0CTL = TASSEL_2 + ID_3 + MC_1; // configure and start timer
// enable interrupts
TA0CCTL0_bit.CCIE = 1; // enable timer interrupts
__enable_interrupt(); // set GIE in SR
}
#pragma vector = TIMER0_A0_VECTOR
__interrupt void myTimerISR(void)
{
LED1 = ~LED1;
}

Resources