I add this header on my C program. And it gives me no such file or directory.
Here is that error: fatal error: avr/io.h: No such file or directory.
Here is all of my code:
#include <avr/io.h>
int main(void)
{
DDRB |= (1 << PB5); // Set PB5 as output
while (1)
{
PORTB |= (1 << PB5); // Turn on LED
_delay_ms(1000); // Wait for 1 second
PORTB &= ~(1 << PB5); // Turn off LED
_delay_ms(1000); // Wait for 1 second
}
return 0;
}
Related
I wrote interrupt handler code here. The purpose of my code is to interrupt when I press the button. However, there is a problem. When the button is pressed, it interrupts and enters the handler, but does not increase the Buttonpress. I see the debugger reads buttonpress++, but after exiting the handler, the code freezes when it comes to the switch. Buttonpress = 1 does not happen. What is the reason of this? Do I need to assign the variable differently when assigning it?
Here is my Code :
/* 1 sec is 1600000 */
void delay(volatile uint32_t);
uint32_t ButtonPress = 0;
/* Interrupt Handlers */
void EXTI0_1_IRQHandler(void){
ButtonPress++;
EXTI->RPR1 |= (1U << 1);
}
int main(void) {
uint32_t ButtonPress = 0;
/* Enable GPIOA clock */
RCC->IOPENR |= (1U << 0);
/* Setup PA0 as output */
GPIOA->MODER &= ~(3U << 2*0);
GPIOA->MODER |= (1U << 2*0);
/* Setup PA1 as input */
GPIOA->MODER &= ~(3U << 2*1);
GPIOA->MODER |= (0U << 2*1);
/* External interrupt at PA1 port */
EXTI->EXTICR[0] |= (0U << 8*1);
/* Mask and Rising on Px1 */
EXTI->IMR1 |= (1U << 1);
EXTI->RTSR1 |= (1U << 1);
EXTI->FTSR1 |= (1U << 1);
/* Setup NVIC */
NVIC_SetPriority(EXTI0_1_IRQn, 0);
NVIC_EnableIRQ(EXTI0_1_IRQn);
while(1) {
switch(ButtonPress){
case 0:
/* Turn off LED */
GPIOA->ODR = (0U << 0);
break;
case 1:
/* Turn on LED 2sec interval */
GPIOA->ODR |= (1U << 0);
delay(3200000);
GPIOA->ODR ^= (1U << 0);
delay(3200000);
break;
case 2:
/* Turn on LED 1sec interval */
GPIOA->ODR |= (1U << 0);
delay(1600000);
GPIOA->ODR ^= (1U << 0);
delay(1600000);
break;
case 3:
/* Turn on LED 0.5sec interval */
GPIOA->ODR |= (1U << 0);
delay(800000);
GPIOA->ODR ^= (1U << 0);
delay(800000);
break;
case 4:
/* Turn on LED 0.1sec interval */
GPIOA->ODR |= (1U << 0);
delay(160000);
GPIOA->ODR ^= (1U << 0);
delay(160000);
break;
case 5:
/* Turn on LED */
GPIOA->ODR |= (1U << 0);
break;
case 6:
/* Button Clear */
ButtonPress = 0;
break;
}
}
return 0;
}
void delay(volatile uint32_t s) {
for(; s>0; s--);
}
`
I wrote interrupt handler code here. The purpose of my code is to interrupt when I press the button. However, there is a problem. When the button is pressed, it interrupts and enters the handler, but does not increase the Buttonpress. I see the debugger reads buttonpress++, but after exiting the handler, the code freezes when it comes to the switch. Buttonpress = 1 does not happen. What is the reason of this? Do I need to assign the variable differently when assigning it?
You have declared the ButtonPress variable twice: once in the global scope and once in main. When the interrupt is called, only the global scope version is in scope and therefore that variable is incremented. When it comes to the switch statement in main however, the other variable is in (a smaller) scope and so that variable is used instead. To fix this, you could remove the declaration of ButtonPress at the beginning of main.
How to write C program in atmel studio to read and write to same port B. I want to read from port B pin 4 and write to the same port B but on pin 5. I have the following:
#include
int main(void)
{
DDRB = 0b00100000;
while(1)
{
PORTB = PINB;
}
}
ofcourse not working, cannot find a tutorial on that on the net.
thanks
Something fast:
int main() {
//....
//Init your pins and so on
//....
while (1) {
if ((PINB & (1 << 4))) {
PORTB |= 1 << 5;
} else {
PORTB &= ~(1 << 5);
}
}
}
I have a problem to communicate from an Atmega3216PU to a at42qt2100.
The datasheets are: Atmega32PU16 and AT42QT2100
This is my code:
#include <avr/io.h>
#include <util/delay.h>
#include <stdio.h>
#define F_CPU 16000000
#define UART_BAUD_RATE 9600
#define UART_BAUD_REGISTERS (((F_CPU / (UART_BAUD_RATE * 16UL))) - 1)
int printCHAR(char character, FILE *stream)
{
while ((UCSRA & (1 << UDRE)) == 0) {};
UDR = character;
return 0;
}
FILE uart_str = FDEV_SETUP_STREAM(printCHAR, NULL, _FDEV_SETUP_RW);
void setup(){
// Init SIO
UCSRB |= (1 << RXEN) | (1 << TXEN);
UCSRC |= (1 << URSEL) | (1 << UCSZ0) | (1 << UCSZ1);
UBRRL = UART_BAUD_REGISTERS;
fprintf(&uart_str, "");
stdout = &uart_str;
printf("");
//Init spi
//set MOSI, SCK and SS output, all others input
DDRB |= (1<<DDB7)|(1<<DDB5)|(1<<DDB4);
SPCR |= (1<<SPE)|(1<<MSTR)|(1<<SPR1)|(1<<SPR0)|(1<<CPHA)|(1<<CPOL);
}
void loop(){
uint8_t data = 0b01000000; //Sending this sequence should return device id
printf("Sending: %d \n",data);
_delay_ms(10000);
PORTB &= 0b11101111; // SS auf LOW!! (Pin4)
SPDR = data;
while(!(SPSR & (1<<SPIF)));
PORTB |= (1<<PB4); // SS auf HIGH!! (Pin4)
printf("Receiving: %d \n",SPDR);
_delay_ms(10000);
}
void main(){
setup();
while(1){
loop();
}
}
I should get an answer from the at42qt2100 with the device id 108 but i always get 0. This ist the output: Sending: 64 Receiving: 0
Does anybody see a misconfiguration?
I did a quick overview of the AT42QT2100 datasheet that you reference and I see a couple of problems right away:
After SS is set low, the host must wait >2us (in Free Run mode) before starting SCK. You are immediately initiating a SPI transfer and, if you are running a 16MHz, that means you may be starting the transmission as soon as 62.5ns after setting SS low.
The datasheet also says that the host must send 3 data bytes within 10ms or the transaction will be treated as an error and the communication exchange will be reset. You are sending 1 byte and then waiting 20s before sending the next byte.
The datasheet says that the device settings become active after the 3 bytes have been sent. That means that 3 more bytes must be sent to get the response to your command.
You should be doing something more along the lines of this:
#define NUM_DATA_BYTES 3
void loop(){
uint8_t sendData[NUM_DATA_BYTES] =
{
0b01000000, /* Device Version Command and default values. */
0b00000000, /* Default Value for Byte 2. */
0b11000000, /* Default Value for Byte 3. */
};
uint8_t receiveData[NUM_DATA_BYTES] = { 0 };
uint8_t i;
PORTB &= 0b11101111; // SS auf LOW!! (Pin4)
/* Ensure that >2us delay requirement is met. Although, the
for() loop below will probably introduce enough delay. */
_delay_ms(1);
/* Send command data. */
for (i = 0; i < NUM_DATA_BYTES; i++)
{
SPDR = sendData[i];
while(!(SPSR & (1<<SPIF)));
}
PORTB |= (1<<PB4); // SS auf HIGH!! (Pin4)
/* Delay here may be unnecessary, but it ensures that timing
issues do not occur. */
_delay_ms(1);
PORTB &= 0b11101111; // SS auf LOW!! (Pin4)
_delay_ms(1);
/* Receive device response data. */
for (i = 0; i < NUM_DATA_BYTES; i++)
{
SPDR = sendData[i];
while(!(SPSR & (1<<SPIF)));
receiveData[i] = SPDR;
printf("Receiving byte %d: %d \n", (i + 1), receiveData[i]);
}
PORTB |= (1<<PB4); // SS auf HIGH!! (Pin4)
_delay_ms(10000);
}
I am sure this code is not perfect, but it should help to get you on the right track. Good luck!
I'm trying to get an arduino running C Code for a LCD display.
Compiling and transmitting and executing C code works fine, tried some LED flashing.
All wires should be OK too, when using the 'native' Arduino Library for LCD displays, everything works great, so it must be a code error I can't find :(
I'm trying to communicate with the LCD via 4 data-wire mode. Control and data pins are on the same port.
Here's the code:
//CPU-Clock Frequency
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
// Definitions:
#define LED_PIN PB5 //PB5 = Arduino Pin 13 (with LED)
#define COMPARE_REG OCR0A
#define TIMER_PIN OC0A
#define TIMER_CONTROL_REGISTER TCCR0A
#define LCD_PORT PORTD
#define LCD_PORTDIR DDRD
//controlpins:
#define RS_PIN PD0
#define RW_PIN PD1
#define ENABLE_PIN PD2
//datapins:
#define DB_7 PD7
#define DB_6 PD6
#define DB_5 PD5
#define DB_4 PD4
//Defined command parameters
#define CLEAR 0x01
// Methods
void sleep(uint16_t sleepTime){
for(;sleepTime>0;sleepTime--){ _delay_ms(1);}
}
void lcd_enable(){
LCD_PORT |= (1<<ENABLE_PIN);
//TODO: wait for busy?
sleep(5);
LCD_PORT &= !(1<<ENABLE_PIN);
sleep(5);
}
void lcd_pushOut(unsigned int data){
LCD_PORT &= (0x0F);
LCD_PORT |= (data & 0xF0);
lcd_enable();
LCD_PORT &= (0x0F);
LCD_PORT |= (data & 0x0F) << 4;
lcd_enable();
}
void lcd_command(unsigned int command){
unsigned short int tmp = (LCD_PORT & 0x0F); //speichere alte Steuerleitungen
LCD_PORT &= !(1<<RS_PIN);
lcd_pushOut(command);
LCD_PORT |= (1<<RS_PIN);
LCD_PORT |= tmp; //setze Steuerleitungen zurück
}
void lcd_init(){
sleep(15); //wait for LCD init
LCD_PORTDIR = 0xFF; //make port of LCD output.
LCD_PORT &= !(1<<RW_PIN); //write, dont read.
LCD_PORT |= (3<<4); //write '3' to port.
LCD_PORT &= !(1<<RS_PIN); //we give commands, not data!
lcd_enable();
sleep(1);
lcd_enable(); //write '3' to port 2nd time.
LCD_PORT &= 0x0F; //behalte steuersignale bei, setze daten'port' zurück.
LCD_PORT |= (2<<4); //write '2' to port.
lcd_enable();
//from now on LCD is in 4 bit mode.
lcd_pushOut(0x28); // 4 bit, 5x7 pix, 2 line mode
lcd_pushOut(0x06); //cursor rückt weiter, display scrollt
lcd_pushOut(0x0F); //display ein, cursor aus, blinken aus
lcd_pushOut(0x80); //we will write to DDRAM
lcd_pushOut(0x01); //clear display
//begin test writing zeroes.
LCD_PORT |= (1<<RS_PIN); //give data, not commands!
}
void timer_init(){
//DDRA |= (1<<TIMER_PIN); //make timerpin output.
TIMER_CONTROL_REGISTER = 0b10000000; //set timerpin high #bottom, on compare match clear. (0x80)
COMPARE_REG = 256/2; // dutycycle= 50%
}
void setTimerPower(unsigned int percent){ //set PWM Output (high) in %
COMPARE_REG = (percent/100) * 256;
}
int main (void)
{
//INIT
lcd_init();
//timer_init();
while(1){
lcd_command(CLEAR);
}
//now ready to write! let's write 3 zeroes!
lcd_pushOut('0');
lcd_pushOut('0');
lcd_pushOut('0');
/*
sleep(5000);
char c = '0';
while (1) {
lcd_clear();
lcd_pushOut(c++);
sleep(969); // 3x lcd_enable + 1 ms bearbeitungszeit? ... ziemlich großzügig
if(c > 0x7A) //entspricht c > 'z'
c='0';
}
*/
return 0;
}
EDIT: most of the time, LCD just makes black squares all over the first line.
All instances of !(1<<BIT_NUMBER) should be converted to ~(1<<BIT_NUMBER) as ! is a boolean NOT and you're essentially doing !(true) so you get 0 as a result.
Example showing the problem (on x86):
int main( int argc, char* argv[] )
{
printf( "%8.8X %8.8X\n", !(1<<2), ~(1<<2) );
return 0;
}
And output is:
00000000 FFFFFFFB
Change that and you'll at least be further ahead. You should also state which controller is on the LCD to help any further.
I'm having trouble with my 4x20 LCD display.
I've been looking at a numerous guides and code snippets the last few days, but nothing seems to help.
The problem is that the displays shows nothing.
When I compile it on my computer and print it all on my screen, everything seems to be ok.
I would appreciate it if somebody would look through it and see if there are any obvious errors.
Thanks in advance.
// Connection:
//
// Atmega32 LCD
// PB0 -> DB4
// PB1 -> DB5
// PB2 -> DB6
// PB3 -> DB7
// PB4 -> RS
// PB5 -> R/W
// PB6 -> E
// PB7 ->
#include <avr/io.h>
#include <util/delay.h>
#define LCDPort PORTB
#define LCDDDR DDRB
#define enable 6 //Enable = on
#define readWrite 5 //Read = on, Write = off
#define RS 4 //Send command = off, send data = on
void checkBusy(void);
void updateLCD(void);
void sendCommand(unsigned char command);
void sendData(unsigned char character);
void sendInitCommand(unsigned char command);
int main(void)
{
LCDDDR |= 15;
LCDDDR |= 1 << enable; //Set control lines as output (high)
LCDDDR |= 1 << readWrite;
LCDDDR |= 1 << RS;
_delay_ms(100); //Wait for LCD to boot
sendInitCommand(0x3); //Init function set 1
_delay_ms(100);
sendInitCommand(0x3); //Init function set 2
_delay_us(100);
sendInitCommand(0x3); //Init function set 3
_delay_us(100);
sendInitCommand(0x2); //Function set (set 4 bit mode)
_delay_us(100);
sendInitCommand(0x28); //Funcion set I=1, N=0, F=0
//sendInitCommand(0x8);
_delay_us(60);
sendInitCommand(0x8); //On/off control D=0, C=0, B=0
//sendInitCommand(0x8);
_delay_us(60);
sendCommand(0x01); //Clear display
//sendInitCommand(0x1);
_delay_ms(60);
sendCommand(0x06); //Entry mode set I/D=1, S=0
//sendInitCommand(0x6);
_delay_us(60);
sendCommand(0x0C); //On/off control D=1, C=0, B=0
//sendInitCommand(0xC);
_delay_us(60);
sendData(0x41); //Display "A"
sendData(0x42); //Display "B"
sendData(0x43); //Display "C"
sendData(0x44); //Display "D"
sendData(0x45); //Display "E"
while(1) {
}
return 0;
}
void checkBusy() {
LCDDDR &= ~15; //Set data DDR lines read (low)
/* LCDPort |= 1 << readWrite; //Forget read for now - use delay instead
LCDPort &= ~1 << RS;
while((LCDPort & 15) >= 0x8) {
updateLCD();
}
*/
_delay_ms(50);
LCDDDR |= 15; //Set data lines DDR to write (high)
}
void updateLCD() {
LCDPort |= 1 << enable; //Enable
asm volatile ("nop");
asm volatile ("nop");
LCDPort &= ~1 << enable; //Disable
}
void sendCommand(unsigned char command) {
checkBusy();
LCDPort &= ~(1 << readWrite | 1 << RS); //Set R/W and RS low (write command)
LCDPort |= (command >> 4) & 15; //Send 4 ms bits
updateLCD();
LCDPort &= ~15;
LCDPort |= command & 15; //Send 4 ls bits
updateLCD();
LCDPort &= ~15; //Clear data lines
}
void sendData(unsigned char character) {
checkBusy();
LCDPort &= ~1 << readWrite; //Set R/W low and RS high (write data)
LCDPort |= 1 << RS;
LCDPort |= (character >> 4 & 15); //Send 4 ms bits
updateLCD();
LCDPort &= ~1 << readWrite;
LCDPort &= ~15;
LCDPort |= 1 << RS;
LCDPort |= (character & 15); //Send 4 ls bits
updateLCD();
LCDPort &= ~15; //Clear data lines
}
void sendInitCommand(unsigned char command) {
LCDPort &= ~(1 << readWrite | 1 << RS); //Set R/W and RS low (write command)
LCDPort |= command & 15;
updateLCD();
LCDPort &= ~15; //Clear data lines
}
Seems this is a HD44780 compatible Controller.
Note that every 4x20 Display is a 2x40 in real which is cutted in the middle. This can be implemented with one Display Controller, but the Display need several Drivers.
Get an eyeful of this:
nonetheless you can interface the Display in 4-Bit Mode.
Here is a sample how to Interface the 4x20 in Bit Mode
(note that Pin15 (LED+) and Pin16 (LED-) are missing, thats only the backlight pins). Dont forget to connect Pin5 (R/W) to GND.
A very good lib to interfacing a HD44780 4x20 is written by Peter Fleury:
http://homepage.hispeed.ch/peterfleury/avr-software.html#libs
in section "LCD library for HD44870 based LCD's" give it a try