Tux12Fun
06.04.2020, 21:36
Hallo,
vielleicht kann mir jemand helfen. Ich bin echt am verzweifeln.
Ich habe ein bisschen C Programmiert und bin auf ein Problem gestoßen.
Ich weiß echt nicht mehr weiter und finde einfach den Fehler nicht.
Sobald ich in der Funktion get_BTData(char mode) eine atoi/atol oder scanf Funktion einbaue,
löst der ATMEGA8 bei USART_Init(9600); einen reboot aus.
Das sehe ich daran, dass mein Programm folgendes verhalten zeigt.
OHNE ATOL
==========
LED blinkt grün 2x
LED blinkt blau 2x
LED geht aus und leuchtet dann durch gehend blau.
-- Der ATMEGA wartet auf Kommandos vom BT Module
Jetzt ändere ich nur eine Zeile (143 in der main.c) pl_valid_time_sec = atol(spl_buffer);
===========================
LED blinkt grün 2x
LED blinkt blau 2x
LED blinkt grün 2x
LED blinkt blau 2x
LED blinkt grün 2x
LED blinkt blau 2x
....
Ich versteh die Welt nicht mehr, baue ich die atol Zeile wieder aus, geht es wieder.
Ich habe auch schon an eine Compiler Optimierung oder einen Speicher Überlauf gedacht.
Aber müsste da nicht gcc eine Warnung ausgeben.
Es gab auch keine Änderung wenn ich zwischen -os oder -o2 wechsel. ( avr-gcc (Gentoo 8.3.0-r1 p1.1) 8.3.0)
Vielleicht habt ihr noch eine Idee der ATMEGA8A läuft bei 2Mhz das BT Module ist ein HC-05
main.c
#define MCU atmega8
#define F_CPU 2000000UL
//-U lfuse:w:0xe2:m -U hfuse:w:0xd9:m
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <inttypes.h>
#include <stdlib.h>
#include <stdio.h>
#include <avr/eeprom.h>
#define EEPROM_DEF 0xFF
#include "USART_RS232_H_file.h" /* include USART library */
#define UART_IN_BUFFER_LEN 512
#define BT_EN_REGISTER DDRC
#define BT_EN_PORT PORTC
#define BT_EN_PIN PC0
#define LED_REGISTER DDRC
#define LED_PORT PORTC
#define LED_RED_PIN PC5
#define LED_GREEN_PIN PC4
#define LED_BLUE_PIN PC3
uint8_t gEi_initCode EEMEM = 123;
long gl_remaining_time = 15;
char gc_intrusion_detected = 0;
char gi_wakeup_pressed =0;
char* gs_verificationCode = "ddd";
//Data from App
char pc_code_sement[UART_IN_BUFFER_LEN];
long pl_valid_time_sec = 0;
long pl_lock_time_sec = 0;
int pi_multiplikator = 0;
char bitRead(char *x, char n) {
return (*x & (1 << n)) ? 1 : 0;
}
void my_sleep(uint16_t sec){
for (unsigned short int i =0; i < sec; i++){
_delay_ms(1000);
}
}
uint8_t uart_getc(uint8_t timeout){
uint32_t i_timeout = timeout;
uint32_t runntime = 0;
while (!(UCSRA & (1<<RXC))){ // warten bis Zeichen verfuegbar
runntime++;
if (runntime >= F_CPU){
runntime=0;
i_timeout--;
if (i_timeout == 0){
return '\0';
}
}
}
return UDR; // Zeichen aus UDR an Aufrufer zurueckgeben
}
void uart_gets( char* Buffer, uint32_t MaxLen, uint32_t timeout ){
uint8_t NextChar;
uint32_t StringLen = 0;
NextChar = uart_getc(timeout); // Warte auf und empfange das nächste Zeichen
while( NextChar != '\n' && StringLen < MaxLen - 1 ) { // Sammle solange Zeichen, bis: entweder das String Ende Zeichen kam oder das aufnehmende Array voll ist
*Buffer++ = NextChar;
StringLen++;
NextChar = uart_getc(timeout);
}
*Buffer = '\0'; // Noch ein '\0' anhängen um einen Standard C-String daraus zu machen
}
long getCurrentVoltage(void){
long adc_result = 0; //Gesamtergebnis der Messung des ADC
ADMUX |= (1<<REFS0) | (1<<REFS1) ; //VCC als Referenzspannung für den AD-Wandler
ADMUX |= (1<<MUX3) | (1<<MUX2) | (1<<MUX1); //1.3V Referenzspannung als Eingang für ADC
_delay_ms(2000); //warten bis sich die Referenzspannung eingestellt hat
ADCSRA |= (1<<ADEN); //ADC aktivieren
for (int i=0; i < 11; i++){
ADCSRA |= (1<<ADSC); //Messung starten
while(!(ADCSRA&(1<<ADIF))){
//warten bis Messung beendet ist
}
//Ergebnisse des ADC zwischenspeichern. Wichtig: zuerst ADCL auslesen, dann ADCH
if (i != 0){ adc_result = adc_result + ADCW; }
ADCSRA |= (1<<ADIF); //Bit Freigeben
}
return adc_result;
}
void get_BTData(char mode){
char uart_buffer[UART_IN_BUFFER_LEN];
// Enable Power for Bluetooth
BT_EN_PORT &= ~(1<<BT_EN_PIN);
for(int i=0; i<4; i++){
LED_PORT ^= (1 << LED_BLUE_PIN);
_delay_ms(500);
}
USART_Init(9600); /* initialize USART with 9600 baud rate */
LED_PORT |= (1<<LED_BLUE_PIN);
uart_gets(uart_buffer,UART_IN_BUFFER_LEN,60);
if (uart_buffer[0] == '\0'){ // TIMEOUT
}else if ( (mode=='I') && (uart_buffer[0] == 'I') && (uart_buffer[1] == 'N') && (uart_buffer[2] == 'I') && (uart_buffer[3] == 'T') && (uart_buffer[4] == ':') ){ // INIT CODE
gEi_initCode = atoi(uart_buffer+5);
eeprom_write_byte(&gEi_initCode, gEi_initCode); // schreiben
USART_SendString("KSR_IC:InitCode Saved"); // KeySaveResponse_InformationCode
}else if ( (mode=='I') && (uart_buffer[0] == 'S') && (uart_buffer[1] == 'E') && (uart_buffer[2] == 'T') && (uart_buffer[3] == 'K') && (uart_buffer[4] == ':') ){ // SET KeySafe Code
//Read Init Code from EEPROM
gEi_initCode = eeprom_read_byte(&gEi_initCode);
char spl_buffer[UART_IN_BUFFER_LEN];
uint8_t ele = 0;
// Split up
uint32_t ii=0;
for (uint32_t i=5; i < UART_IN_BUFFER_LEN; i++){
pc_code_sement[i-5] = uart_buffer[i]; //Copy Code
spl_buffer[ii] = uart_buffer[i];
if ((ele == 0) && (uart_buffer[i] == ',')){
spl_buffer[ii] = '\0';
//pl_valid_time_sec = atol(spl_buffer);
ele++;
ii=0;
}else if ((ele == 1) && (uart_buffer[i] == ',')){
spl_buffer[ii] = '\0';
//pl_lock_time_sec = atol(spl_buffer);
ele++;
ii=0;
}else if ((ele == 2) && (uart_buffer[i] == ',')){
spl_buffer[ii] = '\0';
//pi_multiplikator=atoi(spl_buffer);
ele++;
ii=0;
break;
}
ii++;
}
snprintf(uart_buffer, sizeof uart_buffer, "KSR_RT:%ld\nKSR_ES:%ld\nKSR_ID:%s\n", gl_remaining_time,getCurrentVoltage(),gs_verificat ionCode);
USART_SendString(uart_buffer);
}else if ( (uart_buffer[0] == 'G') && (uart_buffer[1] == 'E') && (uart_buffer[2] == 'T') && (uart_buffer[3] == 'S') && (uart_buffer[4] == ':') ){ // GET Status
snprintf(uart_buffer, sizeof uart_buffer, "KSR_RT:%ld\nKSR_ES:%ld\nKSR_ID:%s\n", gl_remaining_time,getCurrentVoltage(),gs_verificat ionCode); /
USART_SendString(uart_buffer);
}else{
USART_SendString("KSR_EC:UnknwonCommand");
}
_delay_ms(5000);
LED_PORT &= ~(1<<LED_BLUE_PIN);
BT_EN_PORT |= (1<<BT_EN_PIN);
}
int main(void){
// Save Power
ACSR = 0x80; // Disable Analogcomparator
ADCSRA = 0; // Disable ADC
// Direction Registers
DDRB = 0x00; // B as input
DDRC = 0x00; // D as Input
DDRD = 0x00; // D as Input
// Set Output Registers
BT_EN_REGISTER |= (1 << BT_EN_PIN); // Bluetooth PWR Controll
LED_REGISTER |= (1 << LED_RED_PIN); // LED as output
LED_REGISTER |= (1 << LED_GREEN_PIN); // LED as output
LED_REGISTER |= (1 << LED_BLUE_PIN); // LED as output
// Ports to LOW (GND no Pullup)
PORTB = 0x00;
PORTC = 0x00;
PORTD = 0x00;
LED_PORT ^= (1 << LED_GREEN_PIN);
_delay_ms(500);
LED_PORT ^= (1 << LED_GREEN_PIN);
_delay_ms(500);
LED_PORT ^= (1 << LED_GREEN_PIN);
_delay_ms(500);
LED_PORT ^= (1 << LED_GREEN_PIN);
_delay_ms(500);
get_BTData('I'); // INIT MODE
while(1){
LED_PORT ^= (1 << LED_GREEN_PIN);
_delay_ms(500);
}
}
Eingebunden ist noch die
* USART_RS232_C_file.c
https://www.electronicwings.com/users/amrutu/codes/hc05_bluetooth_interface_with_atmega
vielleicht kann mir jemand helfen. Ich bin echt am verzweifeln.
Ich habe ein bisschen C Programmiert und bin auf ein Problem gestoßen.
Ich weiß echt nicht mehr weiter und finde einfach den Fehler nicht.
Sobald ich in der Funktion get_BTData(char mode) eine atoi/atol oder scanf Funktion einbaue,
löst der ATMEGA8 bei USART_Init(9600); einen reboot aus.
Das sehe ich daran, dass mein Programm folgendes verhalten zeigt.
OHNE ATOL
==========
LED blinkt grün 2x
LED blinkt blau 2x
LED geht aus und leuchtet dann durch gehend blau.
-- Der ATMEGA wartet auf Kommandos vom BT Module
Jetzt ändere ich nur eine Zeile (143 in der main.c) pl_valid_time_sec = atol(spl_buffer);
===========================
LED blinkt grün 2x
LED blinkt blau 2x
LED blinkt grün 2x
LED blinkt blau 2x
LED blinkt grün 2x
LED blinkt blau 2x
....
Ich versteh die Welt nicht mehr, baue ich die atol Zeile wieder aus, geht es wieder.
Ich habe auch schon an eine Compiler Optimierung oder einen Speicher Überlauf gedacht.
Aber müsste da nicht gcc eine Warnung ausgeben.
Es gab auch keine Änderung wenn ich zwischen -os oder -o2 wechsel. ( avr-gcc (Gentoo 8.3.0-r1 p1.1) 8.3.0)
Vielleicht habt ihr noch eine Idee der ATMEGA8A läuft bei 2Mhz das BT Module ist ein HC-05
main.c
#define MCU atmega8
#define F_CPU 2000000UL
//-U lfuse:w:0xe2:m -U hfuse:w:0xd9:m
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <inttypes.h>
#include <stdlib.h>
#include <stdio.h>
#include <avr/eeprom.h>
#define EEPROM_DEF 0xFF
#include "USART_RS232_H_file.h" /* include USART library */
#define UART_IN_BUFFER_LEN 512
#define BT_EN_REGISTER DDRC
#define BT_EN_PORT PORTC
#define BT_EN_PIN PC0
#define LED_REGISTER DDRC
#define LED_PORT PORTC
#define LED_RED_PIN PC5
#define LED_GREEN_PIN PC4
#define LED_BLUE_PIN PC3
uint8_t gEi_initCode EEMEM = 123;
long gl_remaining_time = 15;
char gc_intrusion_detected = 0;
char gi_wakeup_pressed =0;
char* gs_verificationCode = "ddd";
//Data from App
char pc_code_sement[UART_IN_BUFFER_LEN];
long pl_valid_time_sec = 0;
long pl_lock_time_sec = 0;
int pi_multiplikator = 0;
char bitRead(char *x, char n) {
return (*x & (1 << n)) ? 1 : 0;
}
void my_sleep(uint16_t sec){
for (unsigned short int i =0; i < sec; i++){
_delay_ms(1000);
}
}
uint8_t uart_getc(uint8_t timeout){
uint32_t i_timeout = timeout;
uint32_t runntime = 0;
while (!(UCSRA & (1<<RXC))){ // warten bis Zeichen verfuegbar
runntime++;
if (runntime >= F_CPU){
runntime=0;
i_timeout--;
if (i_timeout == 0){
return '\0';
}
}
}
return UDR; // Zeichen aus UDR an Aufrufer zurueckgeben
}
void uart_gets( char* Buffer, uint32_t MaxLen, uint32_t timeout ){
uint8_t NextChar;
uint32_t StringLen = 0;
NextChar = uart_getc(timeout); // Warte auf und empfange das nächste Zeichen
while( NextChar != '\n' && StringLen < MaxLen - 1 ) { // Sammle solange Zeichen, bis: entweder das String Ende Zeichen kam oder das aufnehmende Array voll ist
*Buffer++ = NextChar;
StringLen++;
NextChar = uart_getc(timeout);
}
*Buffer = '\0'; // Noch ein '\0' anhängen um einen Standard C-String daraus zu machen
}
long getCurrentVoltage(void){
long adc_result = 0; //Gesamtergebnis der Messung des ADC
ADMUX |= (1<<REFS0) | (1<<REFS1) ; //VCC als Referenzspannung für den AD-Wandler
ADMUX |= (1<<MUX3) | (1<<MUX2) | (1<<MUX1); //1.3V Referenzspannung als Eingang für ADC
_delay_ms(2000); //warten bis sich die Referenzspannung eingestellt hat
ADCSRA |= (1<<ADEN); //ADC aktivieren
for (int i=0; i < 11; i++){
ADCSRA |= (1<<ADSC); //Messung starten
while(!(ADCSRA&(1<<ADIF))){
//warten bis Messung beendet ist
}
//Ergebnisse des ADC zwischenspeichern. Wichtig: zuerst ADCL auslesen, dann ADCH
if (i != 0){ adc_result = adc_result + ADCW; }
ADCSRA |= (1<<ADIF); //Bit Freigeben
}
return adc_result;
}
void get_BTData(char mode){
char uart_buffer[UART_IN_BUFFER_LEN];
// Enable Power for Bluetooth
BT_EN_PORT &= ~(1<<BT_EN_PIN);
for(int i=0; i<4; i++){
LED_PORT ^= (1 << LED_BLUE_PIN);
_delay_ms(500);
}
USART_Init(9600); /* initialize USART with 9600 baud rate */
LED_PORT |= (1<<LED_BLUE_PIN);
uart_gets(uart_buffer,UART_IN_BUFFER_LEN,60);
if (uart_buffer[0] == '\0'){ // TIMEOUT
}else if ( (mode=='I') && (uart_buffer[0] == 'I') && (uart_buffer[1] == 'N') && (uart_buffer[2] == 'I') && (uart_buffer[3] == 'T') && (uart_buffer[4] == ':') ){ // INIT CODE
gEi_initCode = atoi(uart_buffer+5);
eeprom_write_byte(&gEi_initCode, gEi_initCode); // schreiben
USART_SendString("KSR_IC:InitCode Saved"); // KeySaveResponse_InformationCode
}else if ( (mode=='I') && (uart_buffer[0] == 'S') && (uart_buffer[1] == 'E') && (uart_buffer[2] == 'T') && (uart_buffer[3] == 'K') && (uart_buffer[4] == ':') ){ // SET KeySafe Code
//Read Init Code from EEPROM
gEi_initCode = eeprom_read_byte(&gEi_initCode);
char spl_buffer[UART_IN_BUFFER_LEN];
uint8_t ele = 0;
// Split up
uint32_t ii=0;
for (uint32_t i=5; i < UART_IN_BUFFER_LEN; i++){
pc_code_sement[i-5] = uart_buffer[i]; //Copy Code
spl_buffer[ii] = uart_buffer[i];
if ((ele == 0) && (uart_buffer[i] == ',')){
spl_buffer[ii] = '\0';
//pl_valid_time_sec = atol(spl_buffer);
ele++;
ii=0;
}else if ((ele == 1) && (uart_buffer[i] == ',')){
spl_buffer[ii] = '\0';
//pl_lock_time_sec = atol(spl_buffer);
ele++;
ii=0;
}else if ((ele == 2) && (uart_buffer[i] == ',')){
spl_buffer[ii] = '\0';
//pi_multiplikator=atoi(spl_buffer);
ele++;
ii=0;
break;
}
ii++;
}
snprintf(uart_buffer, sizeof uart_buffer, "KSR_RT:%ld\nKSR_ES:%ld\nKSR_ID:%s\n", gl_remaining_time,getCurrentVoltage(),gs_verificat ionCode);
USART_SendString(uart_buffer);
}else if ( (uart_buffer[0] == 'G') && (uart_buffer[1] == 'E') && (uart_buffer[2] == 'T') && (uart_buffer[3] == 'S') && (uart_buffer[4] == ':') ){ // GET Status
snprintf(uart_buffer, sizeof uart_buffer, "KSR_RT:%ld\nKSR_ES:%ld\nKSR_ID:%s\n", gl_remaining_time,getCurrentVoltage(),gs_verificat ionCode); /
USART_SendString(uart_buffer);
}else{
USART_SendString("KSR_EC:UnknwonCommand");
}
_delay_ms(5000);
LED_PORT &= ~(1<<LED_BLUE_PIN);
BT_EN_PORT |= (1<<BT_EN_PIN);
}
int main(void){
// Save Power
ACSR = 0x80; // Disable Analogcomparator
ADCSRA = 0; // Disable ADC
// Direction Registers
DDRB = 0x00; // B as input
DDRC = 0x00; // D as Input
DDRD = 0x00; // D as Input
// Set Output Registers
BT_EN_REGISTER |= (1 << BT_EN_PIN); // Bluetooth PWR Controll
LED_REGISTER |= (1 << LED_RED_PIN); // LED as output
LED_REGISTER |= (1 << LED_GREEN_PIN); // LED as output
LED_REGISTER |= (1 << LED_BLUE_PIN); // LED as output
// Ports to LOW (GND no Pullup)
PORTB = 0x00;
PORTC = 0x00;
PORTD = 0x00;
LED_PORT ^= (1 << LED_GREEN_PIN);
_delay_ms(500);
LED_PORT ^= (1 << LED_GREEN_PIN);
_delay_ms(500);
LED_PORT ^= (1 << LED_GREEN_PIN);
_delay_ms(500);
LED_PORT ^= (1 << LED_GREEN_PIN);
_delay_ms(500);
get_BTData('I'); // INIT MODE
while(1){
LED_PORT ^= (1 << LED_GREEN_PIN);
_delay_ms(500);
}
}
Eingebunden ist noch die
* USART_RS232_C_file.c
https://www.electronicwings.com/users/amrutu/codes/hc05_bluetooth_interface_with_atmega