Написание программ на С в Code Vision AVR для контроллеров не имеющих ОЗУ

Маленькие хитрости при работе с Code Vision AVR

CV AVR – хорошая интегрированная среда для написания программ на языке высокого уровня С для микроконтроллеров семейства AVR, АТ90, ATMEGA, АТХ MEGA. Большое спасибо разработчикам за хорошую программу, но есть в ней один существенный недостаток – это отсутствие поддержки контроллеров без оперативной памяти ОЗУ (RAM), а именно ATTINY11, ATTINY12, ATTINY15. Можно попробовать использовать другие компиляторы, но большинство из них такие как ICCTINY, WinAVR так же не поддерживают С для этих контроллеров. Прибегнув к некоторым ухищрениям все таки можно писать программы на С для этих контроллеров. Для этого необходимо, чтобы все переменные были глобальными и размещались в регистрах, последнее достигается путем использования модификатора register при объявлении переменных.

register unsigned char i;
register insigned int k;

При таком объявлении переменных среда сама разместит переменные в регистрах. По умолчанию она разместит их в регистрах с R16 по R21. Если вы хотите использовать регистры по своему усмотрению, то это можно сделать с помощью директивы препроцессора #pragma regalloc- и указать самостоятельно куда поместить ту или иную переменную.

#pragma regalloc-
register char ttp @12;
register int tmp @10;

таким образом компилятор разместит переменную ttp в регистре R12, а переменную tmp в регистрах R10, R11, так как переменная типа int занимает два байта.

Шаг второй, необходимо отключить генерацию startup кода, то есть кода который выполняется до начала работы основной программы. Для этого в свойствах проекта

CodeVisionAVR

На вкладке C Compiler нужно установить флажок внешнего startup файла рис.2. Далее из каталога BIN программы скопировать файл STARTUP.ASM в каталог проекта и подправить его удалив команды очистки памяти SRAM так как ее нет в наших контроллерах изменить регистр косвенной адресации и убрать инициализацию глобальных переменных.

  ;CodeVisionAVR C Compiler  ;(C) 1998-2004 Pavel Haiduc, HP InfoTech s.r.l.    ;EXAMPLE STARTUP FILE FOR CodeVisionAVR V1.24.1 OR LATER    	.EQU __CLEAR_START=0X60 ;START ADDRESS OF SRAM AREA TO CLEAR  				;SET THIS ADDRESS TO 0X100 FOR THE  				;ATmega128 OR ATmega64 CHIPS  	.EQU __CLEAR_SIZE=256   ;SIZE OF SRAM AREA TO CLEAR IN BYTES  	CLI		;DISABLE INTERRUPTS  	CLR  R30  	OUT  EECR,R30	;DISABLE EEPROM ACCESS    ;DISABLE THE WATCHDOG  	LDI  R31,0x18  	OUT  WDTCR,R31  	OUT  WDTCR,R30    	OUT  MCUCR,R30	;MCUCR=0, NO EXTERNAL SRAM ACCESS    ;CLEAR R2-R14  	LDI  R24,13  	LDI  R26,2  	CLR  R27  __CLEAR_REG:  	ST   X+,R30		; В наших контроллерах нет регистра Х, поэтому заменим его на Y	ST   Y+,R30  	DEC  R24  	BRNE __CLEAR_REG      	;CLEAR SRAM  	LDI  R24,LOW(__CLEAR_SIZE)  	LDI  R25,HIGH(__CLEAR_SIZE)  	LDI  R26,LOW(__CLEAR_START)  	LDI  R27,HIGH(__CLEAR_START)  __CLEAR_SRAM:  	ST   X+,R30  	SBIW R24,1  	BRNE __CLEAR_SRAM    ;GLOBAL VARIABLES INITIALIZATION  	LDI  R30,LOW(__GLOBAL_INI_TBL*2)  	LDI  R31,HIGH(__GLOBAL_INI_TBL*2)  __GLOBAL_INI_NEXT:  	LPM  	ADIW R30,1  	MOV  R24,R0  	LPM  	ADIW R30,1  	MOV  R25,R0  	SBIW R24,0  	BREQ __GLOBAL_INI_END  	LPM  	ADIW R30,1  	MOV  R26,R0  	LPM  	ADIW R30,1  	MOV  R27,R0  	LPM  	ADIW R30,1  	MOV  R1,R0  	LPM  	ADIW R30,1  	MOV  R22,R30  	MOV  R23,R31  	MOV  R31,R0  	MOV  R30,R1  __GLOBAL_INI_LOOP:  	LPM  	ADIW R30,1  	ST   X+,R0  	SBIW R24,1  	BRNE __GLOBAL_INI_LOOP  	MOV  R30,R22  	MOV  R31,R23  	RJMP __GLOBAL_INI_NEXT  __GLOBAL_INI_END:  

 

Красным отмечено все, что нужно убрать.

Использование внешнего файла инициализации

Шаг третий, необходимо подключить заголовочный файл. Так как в каталоге INC программы отсутствуют заголовочные файлы для наших контроллеров, то мы можем использовать файл TINY13.h так как на пример tiny13 и tiny 15 имеют практически одинаковый состав регистров расположенных по одним и тем же адресам, но обязательно с оглядкой на datasheet используемого контроллера. В прилагаемом примере два регистра все же отличались, по этому для наглядности сделал дополнительное определение.

При написании программ на С для контроллеров без оперативной памяти необходимо помнить, что эти микросхемы имеют трех уровневый аппаратный стек, в котором хранятся адреса возврата из функций, так, что не стоит увлекаться вложенными функциями, во избежание переполнения стека.

Если предполагается использовать в своей программе прерывания, то обязательно необходимо использовать директиву препроцессора #pragma savereg-, которая предписывает компилятору не сохранять автоматически регистры в память при входе в процедуру обработки прерывания.

#pragma savereg-
#pragma regalloc-
register char ttp @12;

Далее после написания программы и ее компиляции необходимо подправить выходной asm файл который будет находиться в рабочем каталоге проекта. В нем компилятор генерирует команды инициализации стека, которых нет в наших контроллерах. Убрать нужно всего 4 строчки, которые находятся непосредственно перед началом основной программы:

  	.CSEG  	.ORG 0    	.INCLUDE "1.vec"  	.INCLUDE "1.inc"    __RESET:  	.INCLUDE "STARTUP.ASM"    ;STACK POINTER INITIALIZATION  	LDI  R30,LOW(0x9F)  	OUT  SPL,R30    ;DATA STACK POINTER INITIALIZATION  	LDI  R28,LOW(0x70)  	LDI  R29,HIGH(0x70)  	RJMP _main    	.ESEG  	.ORG 0    	.DSEG  	.ORG 0x70  ;          1 #include   ;          2    ;          3 register unsigned char i;  ;          4 void main(void)  

После этого можно компилировать выходной asm файл. Делать это нужно по тому, что мы его немного подправили и тот hex, что сгенерировала программа нам уже не подойдет. Сделать это можно просто, в каталоге BIN программы находится компилятор avrasm2.exe, его можно скопировать в каталог проекта и выполнить команду:
avrasm2.exe –fI –o myfile.hex myfile.asm
Проект часто приходится перекомпилировать, по этому, чтобы не писать в командной строке много раз одно и тоже, можно создать файл с расширением bat (myfile.bat) и записать в него команду приведенную ниже, теперь для перекомпиляции достаточно его запустить и в итоге вы получите готовый к использованию hex файл.

Теперь о программировании контроллера. Специально для вас я собрал маленькое демонстрационное устройство на ATTINY15 состоящее из контроллера, двух резисторов и светодиода, и запрограммировал его.

Схема устройства

Фото устройства

Текст программы на языке С написанный в CVAVR 1.24.8d

  /*********************************************/  /*           Demo project ATTINY15                 */  /*          Cade Vision AVR 1.24.8d                 */  /*               by Panda_Y2K                                */  /*                   2012                                               */  /*********************************************/    #include     sfrb OCR1A=0x2e;    sfrb TCCR1=0x30;  register unsigned char i,j;    void main(void)  {                 GIMSK = 0;  TIMSK0 = 0x00;  TCCR0B = 0x00;  PORTB = 0;     //Clear PORTB  DDRB  = 0x02;  //PORTB.1 out  // CTC = 0, PWM1 = 1, COM1A1 = 1, COM1A0 = 0, CS13 = 0, CS12 = 1, CS11 = 1, CS10 = 1  // CK/4  TCCR1 = 0x67;    while (1)  {   for (i=255; i>0; i--)      {OCR1A = i;       for (j=255; j>0; j--);       };    };        } //end of main               

CVAVR шить контроллер упорно не хотел, но SinaProg вполне справился с задачей.

Внешний вид SinaProg

Программатор использовался USBTiny

Программатор USBTiny

Видео работы устройства можно посмотреть по ссылке.

Скачать исходник

Автор: Panda_Y2K

Теги: