АСВТ 2 семестр ЛР №6

Материал из Национальной библиотеки им. Н. Э. Баумана
Последнее изменение этой страницы: 22:32, 12 мая 2016.


Работа с таймерами и прерываниями (PIC12F675)

Пример 1

Исходные данные. Осуществить переключение значений на ССИ от 0 до 9 с частотой 1 Гц/2 Гц. Вместе с переключением значений должен мигать светодиод. Частота переключается с помощью ключа.

Реализация. Схема реализована с использованием ключа, LED и семисегментного индикатора:

Рис. 1. Схема в Proteus
Рис. 2. Демонстрация работы

Листинг на C.

Для компиляции проекта использовался компилятор MPLab XC8. Для его использования в свойствах проекта необходимо выбрать последний из списка и указать путь (или Proteus определит его автоматически, если он установлен).

#include "xc.h"

// Config word
__CONFIG(FOSC_INTRCIO & WDTE_OFF & PWRTE_ON & MCLRE_OFF & BOREN_ON & CP_OFF & CPD_OFF);

#define FOSC 4000000L // Using Internal Clock of 8 Mhz
#define DS GP5 //data on pin C2
#define ST_CP GP4 //storage register clock input on pin C1
#define SH_CP GP2 //shift register clock input on pin C0
#define testbit(data,bitno) ((data>>bitno)&0x01)
#define BTN1 GP0
#define BTN2 GP1

unsigned int i,x,y;
unsigned char Digit[11] = {0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xBE,0xE0,0xFE,0xF6}; //Array containing all the "digits"

/*
**0x03 hex = 0 dec = 1111 1100 bin	
**0x9F hex = 1 dec = 0110 0000 bin
**0x25 hex = 2 dec = 1101 1010 bin
**0x0D hex = 3 dec = 1111 0010 bin
**0x99 hex = 4 dec = 0110 0110 bin
**0x49 hex = 5 dec = 1011 0110 bin
**0x41 hex = 6 dec = 1011 1110 bin
**0x1F hex = 7 dec = 1110 0000 bin
**0x01 hex = 8 dec = 1111 1110 bin
**0x09 hex = 9 dec = 1111 0110 bin
*/


// Define CPU Frequency
// This must be defined, if __delay_ms() or 
// __delay_us() functions are used in the code
#define _XTAL_FREQ   4000000    


// Main function
void main()
{	
	ANSEL  = 0x00;       // Set ports as digital I/O, not analog input
	ADCON0 = 0x00;	     // Shut off the A/D Converter
	CMCON  = 0x07;	     // Shut off the Comparator
	VRCON  = 0x00;	     // Shut off the Voltage Reference
	TRISIO = 0x0B;       // GP3 input, rest all output
	GPIO   = 0x00;       // Make all pins 0
	
	x = y = 0;
	while (1)
	{
	   if (BTN1 == 0) {
	      __delay_ms(500);
	   }
	   else {
	      __delay_ms(250);
	   }
	   if (y == 1) {
	    x += 1;
	    if (x > 9) {
	      x = 0;
	    }
	    y = 0;  
	   }
	   else {
	    y += 1;
	   }
	   ST_CP=0;
	   SH_CP=0;
	   for (int i=0;i<8;i++){
	       DS=testbit(Digit[x]+y,i);
	       SH_CP=1;
	       SH_CP=0;
	   }
	   ST_CP=1;
	}
}

Как можно видеть из примера выше, код на языке C выглядит значительно меньше и лаконичнее, чем на Ассемблере.

Работа с таймером[1] осуществляется путем использования встроенной функции задержки для обеспечения корректной работы ССИ и LED.

(Вашему преподавателю необязательно знать, как именно Вы выполнили лабу).

Пример 2

Исходные данные. Реализовать последовательное формирование свечения цифры 3 на ССИ. При подаче питания и нажатии на кнопку Reset все светодиоды и индикаторы погашены. При включении тумблера включаются сегменты индикатора в последовательности f, a, b, c, d. После чего раздается щелчок звукогенератора. На индикаторе горит цифра 3. При отключении тумблера гаснут сегменты индикатора в обратной последовательности. Включение тумблера изменяет темп формирования цифры 3.

Реализация. Схема реализована с использованием ключа, звукогенератора и семисегментного индикатора:

Рис. 3. Схема в Proteus
Рис. 4. Демонстрация работы

Листинг на Asm.

#include <p12f675.inc>
processor 12F675
GPIO_last_state equ 0x5c;
GPIO_current_state equ 0x5e;
number equ 0x5f;
RP0 equ 5;
GP0 equ 0;
GP1 equ 1;
GP2 equ 2;
GP3 equ 3;
GP4 equ 4;
GP5 equ 5;
GIE equ 7;
GPIE equ 3;
GPIF equ 0;

org 0x0000
	goto	init;

isr	org 0x0004;
	movf GPIO, 1;
	movf GPIO, 0;
	movwf GPIO_current_state;
	xorwf GPIO_last_state, 0;
	bsf STATUS, RP0;
	andwf TRISIO, 0;
	bcf STATUS, RP0;
	movwf GPIO_last_state;
	btfsc GPIO_last_state, GP0;
		goto GP0_state_changed;
	btfsc GPIO_last_state, GP5;
		goto GP5_state_changed;
return_from_int
	movf GPIO_current_state, 0;
	movwf GPIO_last_state;
	bcf INTCON, GPIF;
	retfie;
org	0x00ff;
init
	bsf STATUS, RP0;
	bsf TRISIO, GP0; set GP0 in  
	bcf TRISIO, GP1; set GP1 out
	bcf TRISIO, GP2; set GP2 out
	bcf TRISIO, GP4; set GP4 out
	bsf TRISIO, GP5; set GP5 in
	bsf IOC, GP0; set GP0 IOC
	bsf IOC, GP5; set GP5 IOC
	movlw 0;
	movwf ANSEL;
	bcf STATUS, RP0;
	bsf T1CON, TMR1ON
	movlw 0xFF;
	movwf CMCON;
	bsf INTCON, GIE; enable all unmasked interrupts
	bsf INTCON, GPIE; enable IOC
	clrf number;
	movf GPIO, 0;
	movwf GPIO_last_state;
	goto $;
	
GP0_state_changed
	btfsc GPIO, 0;
		goto return_from_int;
	btfsc number, 0;
		goto GP0_second_click;
	bcf GPIO, GP1;0
	bsf GPIO, GP4;
	nop;
	bcf GPIO, GP4;
	bcf GPIO, GP1;0
	bsf GPIO, GP4;
	nop;
	bcf GPIO, GP4;
	bcf GPIO, GP1;0
	bsf GPIO, GP4;
	nop;
	bcf GPIO, GP4;
	bcf GPIO, GP1;0
	bsf GPIO, GP4;
	nop;
	bcf GPIO, GP4;
	bcf GPIO, GP1;0
	bsf GPIO, GP4;
	nop;
	bcf GPIO, GP4;
	bsf GPIO, GP1;1
	bsf GPIO, GP4;
	nop;
	bcf GPIO, GP4;
	bsf GPIO, GP1;1
	bsf GPIO, GP4;
	nop;
	bcf GPIO, GP4;
	bcf GPIO, GP1;0
	bsf GPIO, GP4;
	bsf GPIO, GP2;
	nop;
	bcf GPIO, GP4;
	bcf GPIO, GP2;
	
	incf number, 1;
	goto return_from_int;
			
	GP0_second_click
		bsf STATUS, RP0;
		bcf TRISIO, GP0;
		bcf STATUS, RP0;
		bsf GPIO, GP0;	
		;show_green
		bsf GPIO, GP1;1
		bsf GPIO, GP4;
		nop;
		bcf GPIO, GP4;
		bcf GPIO, GP1;0
		bsf GPIO, GP4;
		nop;
		bcf GPIO, GP4;
		bsf GPIO, GP1;1
		bsf GPIO, GP4;
		nop;
		bcf GPIO, GP4;
		bcf GPIO, GP1;0
		bsf GPIO, GP4;
		nop;
		bcf GPIO, GP4;
		bsf GPIO, GP1;1
		bsf GPIO, GP4;
		nop;
		bcf GPIO, GP4;
		bcf GPIO, GP1;0
		bsf GPIO, GP4;
		nop;
		bcf GPIO, GP4;
		bsf GPIO, GP1;1
		bsf GPIO, GP4;
		nop;
		bcf GPIO, GP4;
		bcf GPIO, GP1;0
		bsf GPIO, GP4;
		bsf GPIO, GP2;
		nop;
		bcf GPIO, GP4;
		bcf GPIO, GP2;
		
		incf number, 1;
		goto return_from_int;

GP5_state_changed
	btfsc GPIO, 5;
		goto return_from_int;
	btfsc number, 0;
		goto GP5_second_click;
	bcf GPIO, GP1;0
	bsf GPIO, GP4;
	nop;
	bcf GPIO, GP4;
	bsf GPIO, GP1;1
	bsf GPIO, GP4;
	nop;
	bcf GPIO, GP4;
	bcf GPIO, GP1;0
	bsf GPIO, GP4;
	nop;
	bcf GPIO, GP4;
	bsf GPIO, GP1;1
	bsf GPIO, GP4;
	nop;
	bcf GPIO, GP4;
	bsf GPIO, GP1;1
	bsf GPIO, GP4;
	nop;
	bcf GPIO, GP4;
	bcf GPIO, GP1;0
	bsf GPIO, GP4;
	nop;
	bcf GPIO, GP4;
	bsf GPIO, GP1;1
	bsf GPIO, GP4;
	nop;
	bcf GPIO, GP4;
	bsf GPIO, GP1;1
	bsf GPIO, GP4;
	bsf GPIO, GP2;
	nop;
	bcf GPIO, GP4;
	bcf GPIO, GP2;
	
	incf number, 1;
	goto return_from_int;
	
	GP5_second_click
		bsf STATUS, RP0;
		bcf TRISIO, GP0;
		bcf STATUS, RP0;
		bsf GPIO, GP0;		
		;show_red
		bcf GPIO, GP1;0
		bsf GPIO, GP4;
		nop;
		bcf GPIO, GP4;
		bsf GPIO, GP1;1
		bsf GPIO, GP4;
		nop;
		bcf GPIO, GP4;
		bcf GPIO, GP1;0
		bsf GPIO, GP4;
		nop;
		bcf GPIO, GP4;
		bsf GPIO, GP1;1
		bsf GPIO, GP4;
		nop;
		bcf GPIO, GP4;
		bcf GPIO, GP1;0
		bsf GPIO, GP4;
		nop;
		bcf GPIO, GP4;
		bsf GPIO, GP1;1
		bsf GPIO, GP4;
		nop;
		bcf GPIO, GP4;
		bcf GPIO, GP1;0
		bsf GPIO, GP4;
		nop;
		bcf GPIO, GP4;
		bsf GPIO, GP1;1
		bsf GPIO, GP4;
		bsf GPIO, GP2;
		nop;
		bcf GPIO, GP4;
		bcf GPIO, GP2;
		
		incf number, 1;
		goto return_from_int;
		
end;

Примечания