Форум РадиоКот https://radiokot.ru/forum/ |
|
Проблема при связи SPI и USI AT90CAN128 и Attiny2313 https://radiokot.ru/forum/viewtopic.php?f=57&t=188627 |
Страница 1 из 7 |
Автор: | warptred12 [ Вт июн 06, 2023 13:20:21 ] |
Заголовок сообщения: | Проблема при связи SPI и USI AT90CAN128 и Attiny2313 |
Пишу код для слейва в виде Attiny2313, суть такова: мастер AT90CAN128 отправляет значение частоты и номер генератора по SPI, а слейв принимает сигнал по USI и на основе полученных значений выдает частоту на выходе(переменная fG отвечает за частоту, nG за номер ножки на выходе). Генерация частоты происходит на таймере1, в функции SetUpTim1A(unsigned int Foc) - подставляем значение частоты fG, там расчитывается значение регистра OCR1A. В функции void set_out_pin (unsigned char num) - подставляем значение nG, эта функция подставляет значение заданного вывода МК в функцию прерывания и таким образом генерируется частота. В функции SpiSlaveInit() - выставляются настройки USI и разрешаются внешние прерывания и прерывания по переполнению. В функции прерывания interrupt [EXT_INT1] void ext_int1_isr(void) - проверяется состояние пина PD3: при Falling edge - разрешаются прерывания по переполнению таймера USI, при Rising edge -запрещаются. В функции interrupt [USI_OVERFLOW] void usi_ovf_isr(void) - каждое прерывание считывается по байту входящей информации, и на основании полученных данных устанавливается значение fG и nG, ну и соответственно генерируется чатота на выходе. Но даже без мастера он дергает всеми пинами в произвольном порядке. Проблема заключается в том, что частота присутствует на выходе PB0 тиньки, и она не соответствует отправленной по SPI. Код мастера: Код: void SPI_MasterInit(void) { SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR1)|(1<<SPR0); /* Enable SPI, Master, set clock rate fck/16 */ } void SPI_MasterTransmit(uint8_t cData) { SPDR = cData; /* Start transmission */ while(!(SPSR & (1<<SPIF))); /* Wait for transmission complete */ }void SPITransmitFreq(uint8_t Cnt, double F) { //F- значение частоты, Cnt - номер генератора dFi.w = F*167.77216; //частота передаваемая через SPI, какое-то фиксированное число 167.77216 PORTB &= ~_BV(PB0); SPI_MasterTransmit(Cnt & 0x03);//0x03-маска SPI_MasterTransmit(dFi.b[0]);//флаги передачи SPI_MasterTransmit(dFi.b[1]);//флаги передачи SPI_MasterTransmit(dFi.b[2]);//флаги передачи PORTB |= _BV(PB0); } Код слейва: Код: #include <tiny2313.h> #include <math.h> #include <io.h> #define F_CPU (8000000) #define VFG_TIMER_MAX (65535) #define VFG_DDR DDRB #define VFG_PORT PORTB #define CS PORTD3 // Chip select #define DO PORTB5 // MISO or Data Out #define USCK PORTB7 // Clock typedef union { unsigned long int w ; // w as WORD unsigned int h[2]; // h as HALF-WORD unsigned char b[4]; // b as BYTE } Union32; Union32 dFi; unsigned int fG; unsigned char nG; unsigned int N[]={1,8,64,256,1024}; unsigned char flag_RT = 0; unsigned char ch_num = 0; volatile char reqID = 0; // This is for the first byte we receive, which is intended to be the request identifier volatile unsigned char index = 0; // this is to send back the right element in the array //***********************************************USI************************************************ void SpiSlaveInit() { #asm("cli") USICR = ((1<<USIWM0)|(1<<USICS1)); // Activate 3- Wire Mode and use of external clock but NOT the interrupt at the Counter overflow (USIOIE) PORTD |= 1<<CS; // Activate Pull-Up resistor on PD3 PCMSK|=1<<CS; // Active Interrupt on PD3 GIMSK|=1<<PCIE; // General Interrupt Mask Register / PCIE bit activates external interrupts #asm("sei") } // External Interrupt 0 service routine interrupt [EXT_INT1] void ext_int1_isr(void) { if((PIND & (1<<CS))== 0){ // If edge is falling, the command and index variables shall be initialized // and the 4-bit overflow counter of the USI communication shall be activated: reqID = 0; index = 0; flag_RT = 0; USICR |= (1<<USIOIE); USISR = 1<<USIOIF; // Clear Overflow bit } else{ // If edge is rising, turn the 4-bit overflow interrupt off: USICR &= ~(1<<USIOIE); } } interrupt [USI_OVERFLOW] void usi_ovf_isr(void) { switch(reqID) { case 0: ch_num = USIDR; USISR = 1<<USIOIF; // Clear Overflow bit reqID++; break; case 1: dFi.b[0] = USIDR; USISR = 1<<USIOIF; // Clear Overflow bit reqID++; break; case 2: dFi.b[1] = USIDR; USISR = 1<<USIOIF; // Clear Overflow bit reqID++; break; case 3: dFi.b[2] = USIDR; USISR = 1<<USIOIF; // Clear Overflow bit reqID++; flag_RT = 1; break; } } //***********************************************timer1************************************************ void Tim1Init(void) { #asm("cli") TCCR1A = (1<<COM1A0); //toggle on compare TCCR1B = (1<<WGM12)|(1<<CS12)|(1<<CS10); // set timer CTC mode, prescaler 1024 TIMSK = (1<<OCIE1A); #asm("sei") } void SetUpTim1A(unsigned int Foc) //calculate value OCR1A register { unsigned int TimDiv; unsigned char ClockSelect=0; unsigned char i; for(i=0;i<=4;i++) { TimDiv = (F_CPU/(2*16*Foc*N[i])-1); if(TimDiv >= 0 && TimDiv<VFG_TIMER_MAX){ ClockSelect=i+1; break; } } #asm("cli") OCR1A = TimDiv; TCCR1B = (1<<WGM12) | (ClockSelect<<CS10); #asm("sei") } void UpdateTim1A(unsigned int freq) //old value storage { static unsigned int fG_old = 0; if (fG_old != freq) { SetUpTim1A(freq); fG_old = freq; } } void set_out_pin (unsigned char num){ //output pin selection nG=1<<num; VFG_DDR = nG; } interrupt [TIM1_COMPA] void timer1_compa_isr(void) { VFG_PORT = (VFG_PORT^nG)&(nG); } void main(void) { static unsigned int fG_old = 0; SpiSlaveInit(); Tim1Init(); UpdateTim1A(fG); #asm("sei") for(;;) { if (fG_old != fG) { //old value detction SetUpTim1A(fG); fG_old = fG; } nG= ch_num; //generator number fG= dFi.b[0]+dFi.b[1]+dFi.b[2]; //generator frequency if (flag_RT = 1) { set_out_pin (nG); SetUpTim1A(fG); } } } Огрызок схемы электрической принципиальной: [url=https://img.radiokot.ru/files/153456/medium/35nbn9zmek.png] |
Автор: | MOHCTEP [ Вт июн 06, 2023 14:39:51 ] |
Заголовок сообщения: | Re: Проблема при связи SPI и USI AT90CAN128 и Attiny2313 |
1 Смысл плодить темы, не закончив предыдущую? 2 Схема не читается абсолютно. 3 Было ведь написано, что свич у вас заклинен на 0 кейсе. Значит регулировка частот просто недоступна. Зато доступен выбор пина порта В, для выхода генерации, если мастер со славой нормально контачат. Этот вариант вам и предлагалось опробовать и отладить. Потом уже занялись бы частотой. |
Автор: | warptred12 [ Вт июн 06, 2023 16:46:40 ] | ||
Заголовок сообщения: | Re: Проблема при связи SPI и USI AT90CAN128 и Attiny2313 | ||
Добавил архив с схемой(P-CAD) и прошивками ATTINY2313 и AT90CAN128. Добавлено after 23 minutes 3 seconds: 1 Смысл плодить темы, не закончив предыдущую? 2 Схема не читается абсолютно. 3 Было ведь написано, что свич у вас заклинен на 0 кейсе. Значит регулировка частот просто недоступна. Зато доступен выбор пина порта В, для выхода генерации, если мастер со славой нормально контачат. Этот вариант вам и предлагалось опробовать и отладить. Потом уже занялись бы частотой. 1) Я считаю, что тема достаточно сложная и интресная, поэтому вынес отдельно. Также не видел похожих тем. 2) Скинул нормальную. 3) Я не знаю как мне проверить нормально ли они контачат. Добавлено after 5 minutes 50 seconds: Нашел ошибку в функции иницилзаци USI: Код: void SpiSlaveInit() { #asm("cli") USICR = ((1<<USIWM0)|(1<<USICS1)); // Activate 3- Wire Mode and use of external clock but NOT the interrupt at the Counter overflow (USIOIE) PORTD |= 1<<CS; // Activate Pull-Up resistor on PD3 GIMSK|=1<<INT1; // General Interrupt Mask Register //ISC11/ISC10 MCUCR #asm("sei") } Теперь внешние прерывания INT1 работают. В протеусе теперь показывает на всех пинах PB0,PB1,PB2 напряжение. Частота не генерируется.
|
Автор: | MOHCTEP [ Ср июн 07, 2023 02:13:36 ] |
Заголовок сообщения: | Re: Проблема при связи SPI и USI AT90CAN128 и Attiny2313 |
PCAD-а у меня нет, так что схему все одно не увижу. Универсальный вариант - конвертировать в pdf. Акробат есть практически у всех. ![]() Цитата: 3) Я не знаю как мне проверить нормально ли они контачат. Порт В у вас практически пуст, за исключением 5 и 7 битов. Посылаете мастером любой из доступных номеров пина и смотрите светодиодом, осциллографом или что там у вас есть - "переехал" ли генератор на заданную ногу Attiny2313. Этим самым выясните - есть ли вообще хоть какой-то обмен данными, и реагирует ли на него Attiny2313. Отладите эту часть, а потом уже можно заняться и частотой, так как, похоже, придется усложнить протокол обмена данными, включив него и значения reqID. Ну и такие схемы лучше отлаживать в железе. Протеус он такой протеус... |
Автор: | warptred12 [ Ср июн 07, 2023 13:56:00 ] | |||
Заголовок сообщения: | Re: Проблема при связи SPI и USI AT90CAN128 и Attiny2313 | |||
Вот в ПДФе схнма. Добавлено after 1 hour 21 minute 58 seconds: Со стороны мастера все впорядке, он что-то отправляет и это похоже на управляющий сигнал. На стороне слейва только порт PB0 горит, но частоты там нет. Добавлено after 44 minutes 31 second: Ниже прикрепил осцилограмы выходных сигналов. Добавлено after 2 minutes 22 seconds: Вот ссылка на пример с которого писал код организации связи SPI-USI. https://weathergadget.wordpress.com/201 ... unication/ Добавлено after 40 minutes 42 seconds: С мастера все сигналы идут нормально, судя по осцилограмме, а вот слейв вообще не реагирует. Изменил регистры прерываний по внешнему сигналу GIMSK = 1<<INT1, на GIMSK |= 1<<PCIE - маска прерываний по измению уровня входящего сигнала и вернулся к прежней проблеме - 4 Гц на PB0. В прерываниях пробовал дергать пинами и пришел к выводу, что оба прерывания не работают. Также убирал функции расчёта частоты и прерываний Таймера1, результат тот же. Ещё нашел ошибку в том, что неправильно обозвал функцию прерывания по изменению уровня на входе, ошибку исправил - результат тот же.
|
Автор: | MOHCTEP [ Ср июн 07, 2023 15:36:17 ] |
Заголовок сообщения: | Re: Проблема при связи SPI и USI AT90CAN128 и Attiny2313 |
Уже какой-то конструктив... Теперь понятно, что слейв просто не понимает или не видит мастера. Тут возможно или частота обмена данными не "в размер" или USI неверно настроен. |
Автор: | warptred12 [ Ср июн 07, 2023 16:27:35 ] |
Заголовок сообщения: | Re: Проблема при связи SPI и USI AT90CAN128 и Attiny2313 |
Тут возможно или частота обмена данными не "в размер" или USI неверно настроен. По идее частота никак не должна влиять, ведь у меня постоянно идет опрос ножки PD3(CS) при изменении уровня логического сигнала, а прерывание PCIE - управляет прерываниями по переполнению 4-х битного таймера(включает/выключает их), а вот в функции прерывания этого таймера побайтово должны приниматься сигналы и я уже в мейне подставляю полученые байты в переменную fG и nG и там уже высчитывается значение частоты и номер вывода. Еще и для протеуса на работе в компе CPU не хватает и он инфу не в реал тайме отображает, попробую дома прогнать, может результат изменится, но я так думаю, что наврятли. Добавлено after 32 minutes 53 seconds: Вернулся к внешним прерываниям INT1: Код: void SpiSlaveInit() { #asm("cli") USICR = ((1<<USIWM0)|(1<<USICS1)); // Activate 3- Wire Mode and use of external clock but NOT the interrupt at the Counter overflow (USIOIE) GIMSK |= 1<<INT1; MCUCR |= 1<<ISC10; #asm("sei") } // External Interrupt 0 service routine interrupt [EXT_INT1] void ext_int1_isr(void) { if((PIND & (1<<CS))== 0){ // If edge is falling, the command and index variables shall be initialized // and the 4-bit overflow counter of the USI communication shall be activated: reqID = 0; index = 0; flag_RT = 0; USICR |= (1<<USIOIE); USISR = 1<<USIOIF; // Clear Overflow bit } else{ // If edge is rising, turn the 4-bit overflow interrupt off: USICR &= ~(1<<USIOIE); } } В регистре MCUCR установил также прерывания при любом изменении логического уровня на INT1, теперь есть хоть какая-то реакция на изменения входных данных от мастера, при изменении переменных nG и fG в прошивке мастера - меняются выходы и частота на слейве. Но я не знаю пока как это структурировать. |
Автор: | MOHCTEP [ Ср июн 07, 2023 16:28:45 ] |
Заголовок сообщения: | Re: Проблема при связи SPI и USI AT90CAN128 и Attiny2313 |
warptred12 писал(а): По идее частота никак не должна влиять Значит в даташитах ерунду пишут? стр. 138 даташита писал(а): The main features of the USI are: Если учесть, что 4-битный счетчик работает по обоим фронтам входного сигнала, то и "неправильное" прерывание, при завышенной частоте вполне вероятно.• Two-wire Synchronous Data Transfer (Master or Slave, fSCLmax = fCK/16) • Three-wire Synchronous Data Transfer (Master, fSCKmax = fCK/2, Slave fSCKmax = fCK/4) Увидел ваше дополнение. Проблема решена? |
Автор: | warptred12 [ Ср июн 07, 2023 17:21:00 ] | ||
Заголовок сообщения: | Re: Проблема при связи SPI и USI AT90CAN128 и Attiny2313 | ||
На мастере clock rate = fck/16, а как на слейве это настроить непонятно. Добавлено after 1 minute 59 seconds: Увидел ваше дополнение. Проблема решена? Ну теперь пины и частота меняются, но частоты и пины рандомно работают. Так что не решена. Добавлено after 47 minutes 6 seconds: Вот такие крокозябры генерируются на выходе, честно говоря даже не знаю, с чем это может быть связано.
|
Автор: | MOHCTEP [ Ср июн 07, 2023 19:12:02 ] |
Заголовок сообщения: | Re: Проблема при связи SPI и USI AT90CAN128 и Attiny2313 |
Как будто модуляция какая-то присутствует... warptred12 писал(а): На мастере clock rate = fck/16, а как на слейве это настроить непонятно. Здесь надо под приемник подстраиваться. Attiny2313 у вас на 8МГц работает без делителя? Значит частота обмена должна быть не более 2МГц для 2 проводного или 500КГц для трехпроводного соединений. |
Автор: | warptred12 [ Чт июн 08, 2023 11:42:11 ] | ||
Заголовок сообщения: | Re: Проблема при связи SPI и USI AT90CAN128 и Attiny2313 | ||
Частота по линии SCK 32.5 кГц, SS 1 кГц, MOSI 4 кГц. Так же в протеусе подключил SPI DEBUGGER и окончательно убедился что мастер все правильно передает. Частота тактирования аттини и атмеги - 8 МГц. Добавлено after 15 minutes 30 seconds: Сделал скриншот терминала SPI Debuger'а, там все верно: 1 байт - номер генератора(2), 2- байт частота в хексадермальном формате А7(1Гц- это 167), остальные байты нули.
|
Автор: | MOHCTEP [ Чт июн 08, 2023 13:27:13 ] |
Заголовок сообщения: | Re: Проблема при связи SPI и USI AT90CAN128 и Attiny2313 |
Обана! Интрига становится все интереснее. ![]() Появились уже 2!! значимых байта, что, в принципе-то и правильно. Но и вопросы появились: 1. Что такое "остальные байты"? Откуда берутся и зачем вообще нужны? 2. Как и где в коде приемника обрабатывается первый байт и как приемник "понимает" - где какой? |
Автор: | warptred12 [ Чт июн 08, 2023 13:58:13 ] |
Заголовок сообщения: | Re: Проблема при связи SPI и USI AT90CAN128 и Attiny2313 |
Обана! Интрига становится все интереснее. ![]() Появились уже 2!! значимых байта, что, в принципе-то и правильно. Но и вопросы появились: 1. Что такое "остальные байты"? Откуда берутся и зачем вообще нужны? 2. Как и где в коде приемника обрабатывается первый байт и как приемник "понимает" - где какой? 1. Мастер передает 4 байта информации по SPI: 1 байт-номер генератора, он отвечает за то на какой ножке слейва будет генерироваться чатота, это значение подставляется в переменную nG, 3 остальных байта - численное значение частоты в хексадермальном формате, умноженное на число 167. 2. В прерывании USI_OVERFLOW, они передаются последовательно и записываются в объединение dFi, а потом подставляются в переменные nG(номер выходного пина) и fG(частота), а эти переменные подставляются в функции расчета регистра прерываний Таймера1 OCR1A(частота) и в само прерывание Таймера1(номер выходной ножки). СпойлерКод: typedef union { unsigned long int w ; // w as WORD unsigned int h[2]; // h as HALF-WORD unsigned char b[4]; // b as BYTE } Union32; Union32 dFi; void SpiSlaveInit() { #asm("cli") USICR = ((1<<USIWM0)|(1<<USICS1)); // Activate 3- Wire Mode and use of external clock but NOT the interrupt at the Counter overflow (USIOIE) PORTD |= 1<<CS; // Activate Pull-Up resistor on PD3 GIMSK |= 1<<INT1; MCUCR |= 1<<ISC10; #asm("sei") } // External Interrupt 0 service routine interrupt [EXT_INT1] void ext_int1_isr(void) { if((PIND & (1<<CS))== 0){ // If edge is falling, the command and index variables shall be initialized // and the 4-bit overflow counter of the USI communication shall be activated: reqID = 0; index = 0; flag_RT = 0; USICR |= (1<<USIOIE); USISR = 1<<USIOIF; // Clear Overflow bit } else{ // If edge is rising, turn the 4-bit overflow interrupt off: USICR &= ~(1<<USIOIE); } } interrupt [USI_OVERFLOW] void usi_ovf_isr(void) { switch(reqID) { case 0: ch_num = USIDR; USISR = 1<<USIOIF; // Clear Overflow bit reqID++; break; case 1: dFi.b[0] = USIDR; USISR = 1<<USIOIF; // Clear Overflow bit reqID++; break; case 2: dFi.b[1] = USIDR; USISR = 1<<USIOIF; // Clear Overflow bit reqID++; break; case 3: dFi.b[2] = USIDR; USISR = 1<<USIOIF; // Clear Overflow bit reqID++; flag_RT = 1; break; } } void main(void) { static unsigned int fG_old = 0; SpiSlaveInit(); Tim1Init(); UpdateTim1A(fG); #asm("sei") for(;;) { if (flag_RT = 1) { if (fG_old != fG) { //old value detction SetUpTim1A(fG); fG_old = fG; } nG= ch_num; //generator number fG= dFi.b[0]+dFi.b[1]+dFi.b[2]; //generator frequency set_out_pin (nG); SetUpTim1A(fG); } } } |
Автор: | veso74 [ Чт июн 08, 2023 14:04:44 ] |
Заголовок сообщения: | Re: Проблема при связи SPI и USI AT90CAN128 и Attiny2313 |
Не пробовали на реальном устройстве? Proteus ... МК с прерывания ... у меня было много сюрпризов (и потраченные часы на поиск неточностей). |
Автор: | warptred12 [ Чт июн 08, 2023 14:26:44 ] |
Заголовок сообщения: | Re: Проблема при связи SPI и USI AT90CAN128 и Attiny2313 |
veso74, попробую, но мне кажется скорее, что я где-то накосячил или что-то не учел. |
Автор: | MOHCTEP [ Чт июн 08, 2023 14:31:40 ] |
Заголовок сообщения: | Re: Проблема при связи SPI и USI AT90CAN128 и Attiny2313 |
warptred12, Цитата: ... ... case 3: dFi.b[2] = USIDR; USISR = 1<<USIOIF; // Clear Overflow bit reqID++; reqID = 0; flag_RT = 1; break; Попробуйте так. |
Автор: | warptred12 [ Чт июн 08, 2023 14:36:16 ] |
Заголовок сообщения: | Re: Проблема при связи SPI и USI AT90CAN128 и Attiny2313 |
MOHCTEP, не помогло, просто горит пин PB0. Добавлено after 1 minute 45 seconds: На мастере nG(номер ножки) = 2, fG(частота) = 2222. |
Автор: | MOHCTEP [ Чт июн 08, 2023 14:55:22 ] |
Заголовок сообщения: | Re: Проблема при связи SPI и USI AT90CAN128 и Attiny2313 |
Тогда у меня больше вариантов нет. Слепите на макетке реальную схему. Думаю в качестве мастера даже второй Attiny2313 подойдет, для отладки. |
Автор: | warptred12 [ Чт июн 08, 2023 15:55:14 ] | ||
Заголовок сообщения: | Re: Проблема при связи SPI и USI AT90CAN128 и Attiny2313 | ||
Решил проверить кейсы светодиодиками и это дало результаты, в прерываниях инт1 они горят и 1 и 2 кейсы тоже, но 3 и 4 кейс не горят, значит они не работают. Теперь вопрос в том почему они не работают. СпойлерКод: interrupt [EXT_INT1] void ext_int1_isr(void) { if((PIND & (1<<CS))== 0){ PORTD |= (1<<5); //зажечь д5 // If edge is falling, the command and index variables shall be initialized // and the 4-bit overflow counter of the USI communication shall be activated: reqID = 0; index = 0; flag_RT = 0; USICR |= (1<<USIOIE); USISR = 1<<USIOIF; // Clear Overflow bit } else{ // If edge is rising, turn the 4-bit overflow interrupt off: USICR &= ~(1<<USIOIE); PORTD |= (1<<6); //д6 } } interrupt [USI_OVERFLOW] void usi_ovf_isr(void) { switch(reqID) { case 0: PORTD |= (1<<0); //д0 ch_num = USIDR; USISR = 1<<USIOIF; // Clear Overflow bit reqID++; break; case 1: PORTD |= (1<<1); //д1 dFi.b[0] = USIDR; USISR = 1<<USIOIF; // Clear Overflow bit reqID++; break; case 2: PORTD |= (1<<2);//д2 dFi.b[1] = USIDR; USISR = 1<<USIOIF; // Clear Overflow bit reqID++; break; case 3: PORTD |= (1<<4);/д4 dFi.b[2] = USIDR; USISR = 1<<USIOIF; // Clear Overflow bit reqID = 0; //reqID++; flag_RT = 1; break; } }
|
Автор: | MOHCTEP [ Чт июн 08, 2023 16:07:45 ] |
Заголовок сообщения: | Re: Проблема при связи SPI и USI AT90CAN128 и Attiny2313 |
Возможно посылка мастера таки = 2 байтам? Ну и где-то в коде еще гасите светодиоды, через паузу, для динамики. |
Страница 1 из 7 | Часовой пояс: UTC + 3 часа |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |