AVR Раздел по микроконтроллерам компании Atmel - AVR / ATtiny / ATmega / ATMega128 / ATxmega, вопросы по программированию в AVR studio и все, относящееся к AVR... |
10.06.2013, 22:17
|
|
Вид на жительство
Регистрация: 02.11.2008
Сообщений: 319
Сказал спасибо: 17
Сказали Спасибо 11 раз(а) в 11 сообщении(ях)
|
Глючит uasart в mega16
Доброго дня.
Второй день бьюсь с проблемой обмена mega16 с siemens tc35, проект ранее был скомпилирован под winavr 2008 года сборки и прекрасно работал, а сейчас не хочет в avr-gcc (WinAVR 20100110) 4.3.3.
Проблема в том, что при отправке команд по usart в модем, в буфере МК организованном для принятия и обработки ответа от модема находится какая-то билеберда, такое ощущение, что съехала кодировка.
Например отправляю в модем
Код:
|
AT+CMGL="REC UNREAD" |
а в МК в буфере непонятные символы:
Принципиалка ни чем не примечательна, mega16 соединена напрямую с tc35 и от него же питается, RX и TX МК соединенны с TX и RX tc35. Отладку в терминалке получаю с встроенного в tc35 max232. Отлаживаю по jtag через avr dragon
При выдаче команд непосредственно с ПК все работает как сказано в даташите на tc35. Буфер (массив) с ответом от модема хранится в rx_buffer
Что не так?
Сам код:
Код:
|
//Chip type : AVRmega16
//Clock frequency : 8,000000 MHz
#include ‹util/delay.h›
#include ‹avr/interrupt.h›
#include ‹avr/io.h›
#include ‹string.h›
#include ‹avr/pgmspace.h›
#include ‹avr/eeprom.h›
#include ‹stdio.h›
#include ‹stdlib.h›
#include ‹ctype.h›
//переменный для USART
#define FRAMING_ERROR (1‹‹FE)
#define PARITY_ERROR (1‹‹PE)
#define DATA_OVERRUN (1‹‹DOR)
#define DATA_REGISTER_EMPTY (1‹‹UDRE)
#define RX_COMPLETE (1‹‹RXC)
// Буфер - USART Receiver buffer
#define RX_BUFFER_SIZE 100
char rx_buffer[RX_BUFFER_SIZE];
#if RX_BUFFER_SIZE‹256
volatile unsigned char rx_wr_index;
volatile unsigned char rx_rd_index;
volatile unsigned char rx_counter;
#else
volatile unsigned int rx_wr_index;
volatile unsigned int rx_rd_index;
volatile unsigned int rx_counter;
#endif
// This flag is set on USART Receiver buffer overflow
volatile char rx_buffer_overflow;
//переменный для USART закончились
//
char EnterPress=0;
const int timer_val0=20; // число раз отсчета для таймера 0( 1/(8000000/1024/256/45)=0.46 секундs)
volatile unsigned int timer_val0_tmp=0; // переменная для отчсета задержки по таймеру0
volatile unsigned char time0_ok=0; //флаг таймера0
const char szAT[] = "AT\r";
const char szATZ[] = "ATZ\r";
const char szATE0[] = "ATE0\r"; // Echo mode off
const char szATE1[] = "ATE1\r"; //Echo mode on
const char szATCPBS[] = "AT+CPBS=\"SM\"\r"; // выбираем записную книжку SIM
const char szATCPBR1[] = "AT+CPBR=1\r"; // читаем из 1й ячейки SIM
const char szATCPBR2[] = "AT+CPBR=2\r"; // читаем из 2й ячейки SIM
const char szATCPBR3[] = "AT+CPBR=3\r"; // читаем из 3й ячейки SIM
const char szATCPBR4[] = "AT+CPBR=4\r"; // читаем из 4й ячейки SIM
const char szATCPBR5[] = "AT+CPBR=5\r"; // читаем из 5й ячейки SIM
const char szATCMGF1[] = "AT+CMGF=1\r"; // переходим на отправку SMS в текстовом режиме
const char szATCMGL1[] = "AT+CMGL=\"REC UNREAD\"\r"; // проверяем наличие новых SMS сообщений в телефоне в TEXT mode
const char szATCNMI[] = "AT+CNMI=1,1,0,0,1\r"; // задаем отоббражение новых SMS сообщений в телефоне при приходе таковых
const char szATCLIP[] = "AT+CLIP=1\r"; // задаем отображение номера звонящего
const char szATCREG2[] = "AT+CREG=2\r"; // будем выводить после +CREG; информацию о сети
volatile unsigned char time00_ok=0; //флаг таймера0 для отсчета в пять секунд (10 циклов для таймера0)
volatile unsigned int timer_val00_tmp=0; // переменная для отчсета задержки по таймеру0 для 10 отсчетов
#define charge_bat_off (PORTB|=(1‹‹4)) // ставим PINB4 в 1 , сигнал инвертируется, так как стоит P-канальный полевик и открывается минусом!!!
#define charge_bat_on (PORTB&=(~(1‹‹4))) // ставим PINB4 в 0
volatile unsigned char Alarm_count=0; //флаг кол-ва аварий за сессию охраны
volatile unsigned char Dial_count=0; //флаг обзвона номеров из SIM-карты, если 0- не звоним, если от 1 до 5, то звоним на один из пяти номеров
volatile unsigned char SMSRecipientNumber_count=0; //кол-во адресатов, считаных из записной книжки телефона
#define led_error_on (PORTD|=_BV(PD6)) // ставим PINB3 в 1
#define led_error_off (PORTD&= ~_BV(PD6)) // ставим PINB3 в 0
#define led_work_on (PORTD|=_BV(PD5)) // ставим PINB2 в 1
#define led_work_off (PORTD&= ~_BV(PD5)) // ставим PINB2 в 0
#define led_test_on (PORTD|=_BV(PD4)) // ставим PINB1 в 1
#define led_test_off (PORTD&= ~_BV(PD4)) // ставим PINB1 в 0
#define BAUD 9600
#define MYUBRR F_CPU/16/BAUD-1
void USART_Init(unsigned int ubrr)
{
/* Set baud rate */
UBRRH = (unsigned char)(ubrr››8);
UBRRL = (unsigned char)ubrr;
/* Enable receiver and transmitter */
UCSRB = (1‹‹RXEN)|(1‹‹TXEN)|(1‹‹RXCIE);
/* Set frame format: 8data, 1stop bit */
UCSRC = (1‹‹URSEL)|(0‹‹USBS)|(3‹‹UCSZ0);}
//функция выдает в порт RS232 один символ
void USART_Send(unsigned char Txt )
{
while (!(UCSRA&(1‹‹UDRE))){};
UDR=Txt; //send number to USART
}
//функция выдает в порт RS232 строку из сомволов
void USART_Send_srt(char* pTxT)
{
while( 1 )
{
if (! (*pTxT) )
{
break;
}
USART_Send(*pTxT);
++pTxT;
}
}
ISR(USART_RXC_vect)
{
unsigned char status;
unsigned char data;
status=UCSRA;
data=UDR;
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
{
rx_buffer[rx_wr_index]=data;
rx_wr_index ++; // инкремент индекса
if (rx_wr_index ›= RX_BUFFER_SIZE)
{
rx_wr_index=0;
};
++rx_counter;
if (rx_counter ›= RX_BUFFER_SIZE)
{
rx_counter=0;
rx_buffer_overflow=1;
};
if (data==13){
EnterPress=1;
}
}
}
ISR(SIG_OVERFLOW0){
//прерывание таймера0
if (timer_val0_tmp›=timer_val0){
timer_val0_tmp=0;
time0_ok=1;
if (timer_val00_tmp›=10){
time00_ok=1;
timer_val00_tmp=0;
}else{
timer_val00_tmp++;
}
}else {
timer_val0_tmp++;
}
}
unsigned char GSM_Command_Send(PGM_P tXt)
{
led_work_on;
//обнуляем указатели на буфер данных с USART и фгал перевода строки
EnterPress=0;
rx_counter=0;
rx_wr_index=0;
//led_test_on;
//отсылаем в USART AT-команду
USART_Send_srt((char*) tXt);
_delay_ms(1000);
//проверяем что ответил GSM-телефон
time0_ok=0;
while (time0_ok!=1){
if (strstr(rx_buffer, "OK")){
led_error_off;
led_work_off;
led_test_off;
return 0;
} else if (strstr(rx_buffer, "ERROR")){
led_error_off;
led_work_off;
led_test_off;
return 1;
}
}
led_error_on;
led_work_off;
led_test_off;
return 2; //timeout
}
int GSM_Init(void)
{
//инициализируем GSM-телефон, перед дальнейшей работой
if (GSM_Command_Send(szATZ)!=0){ return 1;}
if (GSM_Command_Send(szATE1)!=0){ return 1;}
if (GSM_Command_Send(szATCPBS)!=0){ return 1;}
if (GSM_Command_Send(szATCMGF1)!=0){ return 1;}
if (GSM_Command_Send(szATCNMI)!=0){ return 1;}
if (GSM_Command_Send(szATCLIP)!=0){ return 1;}
if (GSM_Command_Send(szATCREG2)!=0){ return 1;}
return 0;
}
int main(void)
{
// настраиваем порты(ножки)
DDRB=0b11111110; //делаем выходами все порты PINB кроме 0.
//PINB=0b00000001; //выводим на все выходы PORTB 0, кроме 0
PORTB=0b00000001; // и подягиваем на +питания PORTB 0.
DDRD=0b11111110; //делаем выходами все порты PIND, кроме PD0 (RXD USART)
PORTD=0b00000000; // не подтягиваем к питанию
DDRC=0b00000000; //делаем входами все порты PINC
PINC=0b00000000; //выводим на все выходы PORTC 0
PORTC=0b00000000; // и подягиваем на +питания.
//настраиваем UART
USART_Init(MYUBRR);
//включаем таймер 0 для отсчета два раза в секунду
TCNT0=0;
TIMSK=0b00000001; //Overflow Interrupt Enable
TCCR0=0b00000101; //clkI/1024 (From prescaler)
//вырубаем зарядку батареи телефона, на всякий случай, перед инициализацией
charge_bat_off;
//выключаем всю индикацию
led_work_on;
led_error_on;
led_test_on;
_delay_ms(500);
led_work_off;
led_error_off;
led_test_off;
sei(); //разрешаем прерывания глобально
//делаем небольшу. паузу
_delay_ms(1000);
//настраиваем GSM-телефон
GSM_Init();
while(1)
{ //начало бесконечного цикла
if (time0_ok==1){
//обрабатываем прерывание от таймера0
//опрашиваем модем на новые сообщения, раз в 5 секунд
GSM_Command_Send(szATCMGL1);
//обнуляем указатели на буфер данных с USART и флаг перевода строки
cli();
memset(&rx_buffer,'\0',RX_BUFFER_SIZE); //очишаем временнуы массив от данных
sei();
EnterPress=0;
rx_counter=0;
rx_wr_index=0;
time0_ok=0;
}
};// конец бесконечного цикла
}// конец main |
|
|
|
|
10.06.2013, 22:37
|
|
Вид на жительство
Регистрация: 30.12.2006
Адрес: Junktown
Сообщений: 300
Сказал спасибо: 164
Сказали Спасибо 171 раз(а) в 59 сообщении(ях)
|
Re: Глючит uasart в mega16
а F_CPU где задано?
может USART настраивается не на ту скорость, что надо?
__________________
Всегда стремись к недоступному
|
|
|
|
10.06.2013, 22:48
|
|
Почётный гражданин KAZUS.RU
Регистрация: 13.10.2007
Адрес: Беларусь
Сообщений: 8,034
Сказал спасибо: 60
Сказали Спасибо 3,947 раз(а) в 2,303 сообщении(ях)
|
Re: Глючит uasart в mega16
Подсмотри терминалом, что отправляет юсарт, что модем отвечает. Или лучше осциллографом - скорости не совпадают
|
|
|
|
10.06.2013, 22:52
|
|
Вид на жительство
Регистрация: 02.11.2008
Сообщений: 319
Сказал спасибо: 17
Сказали Спасибо 11 раз(а) в 11 сообщении(ях)
|
Re: Глючит uasart в mega16
Сообщение от rear
|
а F_CPU где задано?
может USART настраивается не на ту скорость, что надо?
|
F_CPU в Makefile установлен:
Если настроить явно на не ту скорость, то МК вообще не может ничего отправить в модем и наоборот, это я первым делом проверил, даже скопипастил из даташита настройку usart.
Прикладываю весь проект.
|
|
|
|
10.06.2013, 22:57
|
|
Вид на жительство
Регистрация: 02.11.2008
Сообщений: 319
Сказал спасибо: 17
Сказали Спасибо 11 раз(а) в 11 сообщении(ях)
|
Re: Глючит uasart в mega16
Сообщение от niXto
|
Подсмотри терминалом, что отправляет юсарт, что модем отвечает. Или лучше осциллографом - скорости не совпадают
|
Терминалом и смотрю, когда скорость МК не 9600 то обмена командами вообще нет. Лишних символов или мусора МК не шлет.
|
|
|
|
11.06.2013, 07:51
|
|
Почётный гражданин KAZUS.RU
Регистрация: 13.10.2007
Адрес: Беларусь
Сообщений: 8,034
Сказал спасибо: 60
Сказали Спасибо 3,947 раз(а) в 2,303 сообщении(ях)
|
Re: Глючит uasart в mega16
Обмен командами есть ВСЕгда, контроллеру до лампочки, стандартная у него частота или нет. Просто терминал может помечать такие фреймы как ошибочные и не выводить, а модем становится раком и шлет бред. Контроллер работает от кварца или встроенного генератора? Ставь кварц
|
|
|
|
11.06.2013, 08:18
|
|
Гуру портала
Регистрация: 06.05.2005
Адрес: Краснодар, возле укротворного моря.
Сообщений: 19,094
Сказал спасибо: 2,570
Сказали Спасибо 11,934 раз(а) в 5,983 сообщении(ях)
|
Re: Глючит uasart в mega16
Сообщение от niXto
|
Обмен командами есть ВСЕгда, контроллеру до лампочки, стандартная у него частота или нет. Просто терминал может помечать такие фреймы как ошибочные и не выводить, а модем становится раком и шлет бред. Контроллер работает от кварца или встроенного генератора? Ставь кварц
|
Насколько помнится, модем, чтобы стать раком (или рыбой), ждет 0x0d 0x0a. А пока не получил - молчит. Даже если стал раком - шлет осмысленное сообщение об ошибке. А вот если пургу несет - значит виноват ТС или крыша у него съехала. Но, поскольку с терминалом работает, скорее первое.
__________________
Не бейте больно, ежели чо, ну не удержался... А вааще,
"Мы за все хорошее, против всей х..., По лугам некошеным чтобы шли ступни,
Чтобы миром правила правда, а не ложь, Мы за все хорошее, нас не на...!
..." (Ленинград)
Я не несу ответственности за свои действия в Вашей голове.
|
|
|
|
11.06.2013, 09:48
|
|
Почётный гражданин KAZUS.RU
Регистрация: 13.10.2007
Адрес: Беларусь
Сообщений: 8,034
Сказал спасибо: 60
Сказали Спасибо 3,947 раз(а) в 2,303 сообщении(ях)
|
Re: Глючит uasart в mega16
У меня на квиктеловских М10 с первыми прошивками было такое - там контроллер без кварца (все ножки заняты), поэтому посылал АТ и по ответу ERROR измерял длительности импульсов и калибровал собственный генератор. Так вот периодически модем от такого издевательства становился раком до сброса питания и писал поэмы, переполняя буфер контроллера. На аппаратную ножку выключения не реагировал
|
|
|
|
11.06.2013, 09:48
|
|
Вид на жительство
Регистрация: 02.11.2008
Сообщений: 319
Сказал спасибо: 17
Сказали Спасибо 11 раз(а) в 11 сообщении(ях)
|
Re: Глючит uasart в mega16
Сообщение от akegor
|
Насколько помнится, модем, чтобы стать раком (или рыбой), ждет 0x0d 0x0a. А пока не получил - молчит. Даже если стал раком - шлет осмысленное сообщение об ошибке. А вот если пургу несет - значит виноват ТС или крыша у него съехала. Но, поскольку с терминалом работает, скорее первое.
|
mega8 тактуется от кварца на 8мгц, модем не становится ни в какую "похзицию", он благополучно отвечает на команды МК и пурги от МК не поступает, это видно в терминале в режиме HEX и лишних символов там тоже не видно.
|
|
|
|
11.06.2013, 10:11
|
|
Гражданин KAZUS.RU
Регистрация: 16.06.2005
Сообщений: 945
Сказал спасибо: 25
Сказали Спасибо 175 раз(а) в 124 сообщении(ях)
|
Re: Глючит uasart в mega16
Сообщение от rear
|
может USART настраивается не на ту скорость, что надо?
|
Скорее всего.
Сообщение от TechMike
|
роект ранее был скомпилирован под winavr 2008 года сборки и прекрасно работал, а сейчас не хочет в avr-gcc (WinAVR 20100110) 4.3.3.
|
В это трудно поверить, я не раз старые с-файлы 2006-2009 (виавр, студия 4) подключал к студии 6. Всё отлично без ошибок перекомпилировалось. Да, сами воркспейсы проектов винавр и новой студии несовместимы. Но с-код совпадает полностью.
Ну а по поводу скорости - попробуй задать скорость уарта цифрами, а не формулой. Проверь, на нужной ли частоте запустился кварц (например переключая состояние какой-либо ноги контроллера с заданным периодом). Может конденсаторы на кварце малы-велики (для 8 Мгц это порядка 22-30 пф)?
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 03:33.
|
|