Свежие обсуждения
Микроконтроллеры

Подружить CodeVisionAVR с кусочком кодом

Народ подтолкните пожалуйста в нужном направлении:

Задача: Пытаюсь скомпилить следующий код для приёма байта по SPI в ATMega16 (код взят из даташита по 16ой меге - стр. 132).[/i]
Вот полный код программы:


#include <mega16>

#define DDR_SPI DDRB
#define DD_MISO PORTB.6

#define CMD1 0x01
#define CMD2 0x02
#define CMD3 0x03
#define CMD4 0x04

void SPI_SlaveInit(void)
{
/* Set MISO output, all others input */
DDR_SPI = (1 << DD_MISO);
/* Enable SPI */
SPCR = (1 << SPE);
}

unsigned char SPI_SlaveReceive(void)
{
/* Wait for reception complete */
while(!(SPSR & (1 << SPIF)))
;
/* Return data register */
return SPDR;
}

void main (void){
SPI_SlaveInit();

while (1){

switch(SPI_SlaveReceive())
{
case CMD1:
PORTA = 1;
break;
case CMD2:
PORTA = 2;
break;
case CMD3:
PORTA = 3;
break;
case CMD4:
PORTA = 4;
break;
default:
PORTA = 250;
break;
}

};
}

Ошибки, вылазящие при компилязции, указывают на то, что в стандартных header'ах идущих с CVAVR не прописаны описания регистров: SPSR (и бит SPIF в частности), SPDR.

Порылся в сети - эти регстры описаны в хедерах, идущих с WinAVR.
Но при попытке, дописать недостоющие:

#define SPCR _SFR_IO8(0x0D)
#define SPR0 0
#define SPR1 1
#define CPHA 2
#define CPOL 3
#define MSTR 4
#define DORD 5
#define SPE 6
#define SPIE 7

#define SPSR _SFR_IO8(0x0E)
#define SPI2X 0
#define WCOL 6
#define SPIF 7


взятые из папки WinAVR'a avr\iom16.h в мой заголовок mega16.h получаю теперь ошибку, что компилятор ругается на определение _SFR_IO8(0x0E)
Как исправить это? ) И правильно ли я вообще копаю?

* Я знаю первое что преходит на ум - "Парень, брось и скомпиль в WinAVR" - у мну очень много уже есть в CVAVR и хочу заставить работать его.

Может просто у кого нибудь есть нормальные заголовочные файлы для 16ой меги?

 

в CodeVision ненормальный заголовочный файл?)
А вообще как-то сложно у вас все получилось. В CodeVision есть библиотека spi.h в ней есть одноименная функция
unsigned char spi(unsigned char chr)
Она как и пишет так и читает по spi...

#include <mega16.h>
#include <spi.h>

void main(void)
{
PORTA=0x00;
DDRA=0x00;
PORTB=0x00;
DDRB=0x40; //тут SPI порт
PORTC=0x00;
DDRC=0x00;
PORTD=0x00;
DDRD=0x00;

// Делаем SPI по этим параметрам:
// SPI initialization
// SPI Type: Slave
// SPI Clock Rate: 1000.000 kHz
// SPI Clock Phase: Cycle Half
// SPI Clock Polarity: Low
// SPI Data Order: MSB First
SPCR=0x40;
SPSR=0x00;

unsigned char read=0;
unsigned char write= test;

while (1)
{
//читаем
read=spi();
//пишем
spi(write);
};
}

Но я бы рекомендовал еще сделать прерывание при приеме по SPI. Это упростит обработку.
Для этого после #include пишем:

interrupt [SPI_STC] void spi_isr(void)
{
unsigned char data;
data=SPDR;
// тут обработка
}

и перед рутиной (while (1) там где)

// Чистим флаг прерывания
#asm
in r30,spsr
in r30,spdr
#endasm

// Включаем прерывания
#asm("sei")

и еще
где SPCR=0x40;
меняем на SPCR=0xC0;

Но вообще SPCR, SPSR это ваше дело - я не знаю ни частоты ни параметров вашего SPI. По даташиту - или что проще, в CodeVision есть генератор кода - он все за вас сделает тут

Если используете преревание #include <spi.h> не нужен

Вот и все )

Если чего пишите сюда или в аську или на мыл..

 

2BCluster - спасибо, огромное, что натолкнули на как мне самому кажется более легкое и грамотное решение. Остается в нём только немного разобраться.
Поигрался с генератором кода и предложенным Вами кодом. Заставить работать не получилось =(. Но думаю всё получится. Итак, пока пробую запустить просто, без прерываний.

#include <mega16.h>
#include <spi.h>

// Управляющие коды, которые могут быть переданы
#define CMD1 0x01
#define CMD2 0x02
#define CMD3 0x03
#define CMD4 0x04

unsigned char read;

void main (void){

// инициализируем порты
PORTB=0x00;
DDRB=0x40; //тут SPI порт
PORTF=0x00;
DDRF=0xFF;

// инициализируем SPI
SPCR=0x40;
SPSR=0x00;

while (1){

read = spi(0x00);
/* вот здесь мне непонятно что писать в качестве аргумента spi()? [без аргумента выдает ошибку]. */

switch(read)
{
case CMD1:
PORTA = 0x01;
break;
case CMD2:
PORTA = 0x02;
break;
case CMD3:
PORTA = 0x03;
break;
case CMD4:
PORTA = 0x04;
break;
default:
PORTA = 0xFF;
break;
}
};
}

Не разберусь как используется вызов spi() - если делать конструкцию, как Вы сказали: read=spi();
то выдает ошибку - ему нужен аргумент, для spi() - пошерстил по сети, там везде люди по разному ставят, поэтому вопрос - как с ним работать-то по науке?

* прикрепил схемку, к этой задаче (Мега, получает с ПК управляющий код (байт), анализирует его и выполняет какое то определенное действие (пускай будет моргать светодиодами на порту). Используется SPI, мега получается в режиме salve.) - возможно тоже имеет место быть

Про параметры SPI - особо сказать ничего не могу =( Когда настраивал codewizard'ом - то код как у вас получился. Основное, то что Мега - slave

 

Ну про параметры вы должны что-то знать, например тактовую частоту SPI, MSB или LSB идет первым, и т.д. Но суть не в этом. Вы совершенно правы тут: read = spi(0x00);
аргумент нулевой должен быть. Хотя скорее всего можно любое число туда вписать. В ANSI C нету возможности перегруженные методы делать - поэтому число аргументов фиксировано.

Но все же я не советую пользовать SPI в таком виде. Лучше по прерыванию.

 

На сайте http://123avr.com есть файлы описания от 8 меги до 128 (m8_128.h):
" Определения всех битов для микроконтроллеров
ATmega8 ATmega16 ATmega32 ATmega64 ATmega128 по DataSheets на 2004/12/19
поместите этот файл в папку: CVAVR\inc и включите его в исходник вашей программы вот так:

#include <mega8.h> // это обычно включаемый файл дл выбраного МК
#include <m8_128.h>

Теперь вы можете использовать примеры на
Си из ДШ в том виде как они там написаны." - из описания к файлу.

197592.h

 

действительно К О III М А Р! Он просто везде и от него никак не избавиться! Он наступает снова и снова!

 

Lastic: действительно К О III М А Р! Он просто везде и от него никак не избавиться! Весеннее обострение..

 

ппц, и не лень же....

 

Давал бы чел нормальные конкретные ссылки - только спасибо бы сказали. А отфильтровывать всю "помойку", выискивая в громадной куче навоза жемчужные зерна - уж увольте.
Не понимаю, почему модераторы спят?