Автор работы: Пользователь скрыл имя, 06 Декабря 2012 в 11:54, курсовая работа
В современной электронике микропроцессором называют специальную
микросхему, которая предназначена для выполнения некоего набора сложных функций по управлению тем либо иным электронным устройством.
Микропроцессор – это сердце любого компьютера. Но не только. Те же
технологии, которые применяются в компьютерах, с успехом применяются
и в более простых электронных устройствах.
Введение 3
Структура микроконтроллера 4
Простейшая программа. 7
Прерывания 8
Подключение дисплея (asm) 12
Программа для работы с дисплеем через COM-порт. 15
Литература 18
ldi temp,0
ldi rab, 0
out DDRD, temp ; Записываем ноль в DDRD (порт PD на ввод)
ldi temp, 0xFF ; Записываем число $FF в регистр temp
out DDRB, temp ; Записываем это число в DDRB (порт PB на вывод)
out PORTD, temp ; Записываем то же число в PORTB (потушить светодиод)
out PORTB, temp ; Записываем его же в PORTD (включаем внутр. резисторы)
;----------------------------- Основной цикл--------------------------
ldi temp,0b11000000
out GICR,temp ;Разрешаем прерывания int0,int1
sei
stop:
rjmp stop
prer: clr temp
out GICR,temp ;Запрещаем прерывания int0,int1
sbrc rab, 3
rjmp vikl
vkl: ldi rab,0
out PORTB, rab
ldi rab, 0xFF
ldi temp,0b11000000
out GICR,temp ;Разрешаем прерывания int0,int1
reti
vikl: ldi temp, 0b11010101
out PORTB, temp
ldi rab, 0
ldi temp,0b11000000
out GICR,temp ;Разрешаем прерывания int0,int1
reti
Поставим перед собой задачу написания программы на ассемблере, для работы с дисплеем. А именно программа будет выводить на дисплей некоторый текст. Для написания программы, добавим библиотеку hd44780.asm, текст которой представлен ниже. В ней происходит инициализация дисплея, выбор порта для подключения, настройки курсора и описание функций.
#define HD44780_CLEAR 0x01
#define HD44780_HOME 0x02
#define HD44780_ENTRY_MODE 0x04
#define HD44780_EM_SHIFT_CURSOR 0
#define HD44780_EM_SHIFT_DISPLAY 1
#define HD44780_EM_DECREMENT 0
#define HD44780_EM_INCREMENT 2
#define HD44780_DISPLAY_ONOFF 0x08
#define HD44780_DISPLAY_OFF 0
#define HD44780_DISPLAY_ON 4
#define HD44780_CURSOR_OFF 0
#define HD44780_CURSOR_ON 2
#define HD44780_CURSOR_NOBLINK 0
#define HD44780_CURSOR_BLINK 1
#define HD44780_DISPLAY_CURSOR_SHIFT
#define HD44780_SHIFT_CURSOR 0
#define HD44780_SHIFT_DISPLAY 8
#define HD44780_SHIFT_LEFT 0
#define HD44780_SHIFT_RIGHT 4
#define HD44780_FUNCTION_SET 0x20
#define HD44780_FONT5x7 0
#define HD44780_FONT5x10 4
#define HD44780_ONE_LINE 0
#define HD44780_TWO_LINE 8
#define HD44780_4_BIT 0
#define HD44780_8_BIT 16
#define HD44780_CGRAM_SET 0x40
#define HD44780_DDRAM_SET 0x80
.equ LCD_PORT = PORTC
.equ LCD_DDR = DDRC
.equ LCD_PIN = PINC
.equ LCD_D4 = 0
.equ LCD_D5 = 1
.equ LCD_D6 = 2
.equ LCD_D7 = 3
.equ LCD_RS = 4
.equ LCD_EN = 5
;-----------------------------
LCD_WriteNibble:
sbi LCD_PORT, LCD_EN
sbrs r16, 0
cbi LCD_PORT, LCD_D4
sbrc r16, 0
sbi LCD_PORT, LCD_D4
sbrs r16, 1
cbi LCD_PORT, LCD_D5
sbrc r16, 1
sbi LCD_PORT, LCD_D5
sbrs r16, 2
cbi LCD_PORT, LCD_D6
sbrc r16, 2
sbi LCD_PORT, LCD_D6
sbrs r16, 3
cbi LCD_PORT, LCD_D7
sbrc r16, 3
sbi LCD_PORT, LCD_D7
cbi LCD_PORT, LCD_EN
ret
;-----------------------------
LCD_WriteData:
sbi LCD_PORT, LCD_RS
push r16
swap r16
rcall LCD_WriteNibble
pop r16
rcall LCD_WriteNibble
clr XH
ldi XL,250
rcall Wait4xCycles
ret
;-----------------------------
LCD_SetAddressDD:
ori r16, HD44780_DDRAM_SET
rcall LCD_WriteCommand
ret
;-----------------------------
LCD_Init:
sbi LCD_DDR, LCD_D4
sbi LCD_DDR, LCD_D5
sbi LCD_DDR, LCD_D6
sbi LCD_DDR, LCD_D7
sbi LCD_DDR, LCD_RS
sbi LCD_DDR, LCD_EN
cbi LCD_PORT, LCD_RS
cbi LCD_PORT, LCD_EN
ldi r16, 100
rcall WaitMiliseconds
ldi r17, 3
InitLoop:
ldi r16, 0x03
rcall LCD_WriteNibble
ldi r16, 5
rcall WaitMiliseconds
dec r17
brne InitLoop
ldi r16, 0x02
rcall LCD_WriteNibble
ldi r16, 1
rcall WaitMiliseconds
ldi r16, HD44780_FUNCTION_SET | HD44780_FONT5x7 | HD44780_TWO_LINE | HD44780_4_BIT
rcall LCD_WriteCommand
ldi r16, HD44780_DISPLAY_ONOFF | HD44780_DISPLAY_OFF
rcall LCD_WriteCommand
ldi r16, HD44780_CLEAR
rcall LCD_WriteCommand
ldi r16, HD44780_ENTRY_MODE |HD44780_EM_SHIFT_CURSOR | HD44780_EM_INCREMENT
rcall LCD_WriteCommand
ldi r16, HD44780_DISPLAY_ONOFF | HD44780_DISPLAY_ON | HD44780_CURSOR_ON | HD44780_CURSOR_BLINK
rcall LCD_WriteCommand
ret
;-----------------------------
#ifndef F_CPU
#error "F_CPU must be defined!"
#endif
#if F_CPU < 4000000
#warning "F_CPU too low, possible wrong delay"
#endif
#define CYCLES_PER_US (F_CPU/1000000)
#define C4PUS (CYCLES_PER_US/4)
#define DVUS(x) (C4PUS*x)
;-----------------------------
; Input : XH:XL - number of CPU cycles to wait (divided by four)
;-----------------------------
Wait4xCycles:
sbiw XH:XL, 1
brne Wait4xCycles
ret
;-----------------------------
; Input : r16 - number of miliseconds to wait
;---------- WaitMiliseconds:
push r16
WaitMsLoop:
ldi XH,HIGH(DVUS(500))
ldi XL,LOW(DVUS(500))
rcall Wait4xCycles
ldi XH,HIGH(DVUS(500))
ldi XL,LOW(DVUS(500))
rcall Wait4xCycles
dec r16
brne WaitMsLoop
pop r16
ret
;-----------------------------
; End of file
;-----------------------------
;**** Subroutine Register Variables
.def drem8u =r15 ;remainder
.def dres8u =r16 ;result
.def dd8u =r16 ;dividend
.def dv8u =r17 ;divisor
.def dcnt8u =r18 ;loop counter
;***** Code
div8u:
sub drem8u,drem8u ; clear remainder and carry
ldi dcnt8u,9 ; init loop counter
d8u_1:
rol dd8u ; shift left dividend
dec dcnt8u ; decrement counter
brne d8u_2 ; if done
ret ; return
d8u_2:
rol drem8u ; shift dividend into remainder
sub drem8u,dv8u ; remainder = remainder - divisor
brcc d8u_3 ; if result negative
add drem8u,dv8u ; restore remainder
clc ; clear carry to be shifted into result
rjmp d8u_1 ; else
d8u_3: sec ; set carry to be shifted into result
rjmp d8u_1
Подключив библиотеку hd44780.asm программа вывода текста становиться очень простой. Работа программы хорошо описана в комментариях.
.include "m8def.inc";Используем Мегу16
;=============================
#define F_CPU (8000000)
;Здесь идёт определение тактовой частоты. Нужно для
;библиотеки задержек,
;Частота в Герцах.
;=============================
ldi r16,low(RAMend)
out SPL,r16
ldi r16,high(RAMend)
out SPH,r16
;Инициализация стека. Обязательно!!!
;-----------------------------
rcall lcd_init;Инициализация дисплея.
;-----------------------------
ldi r16, 'K'
rcall LCD_WriteData
ldi r16, 'e'
rcall LCD_WriteData
ldi r16, 'n'
rcall LCD_WriteData
ldi r16, 't'
rcall LCD_WriteData
ldi r16,0x40
rcall LCD_SetAddressDD
; Переходим ко второй строке, поэтому запись будем начинать с 40-го адреса
ldi r16, 'P' ;Выводим на дсплей следующую строку
rcall LCD_WriteData
ldi r16, 'a'
rcall LCD_WriteData
ldi r16, 'v'
rcall LCD_WriteData
ldi r16, 'e'
rcall LCD_WriteData
ldi r16, 'l'
rcall LCD_WriteData
;-----------------------------
main:
;В главном цикле мы ничего не делаем.
rjmp main
;-----------------------------
.include "hd44780.asm"; Подключение библиотеки для работы с дисплеем.
Как упоминалось выше, микроконтроллер может работать и с компьютером через последовательный порт UART (universal asynchronous receiver-transmitter, “универсальный асинхронный приемопередатчик”).
Поставим перед собой задачу: микроконтроллер принимает через COM-порт некоторую строку, вводимую пользователем на компьютере, а затем выводит ее на дисплей.
Рассмотрим программу для микроконтроллера, написанную в среде mikroC PRO for AVR на языке программирования С. В начале программы происходит инициализация дисплея – указывается, каким образом микроконтроллер будет соединен с дисплеем. Очень важно установить частоту приема-передачи данных одинаковой с частотой COM-порта. В нашей программе сделаем ее равной 9600. Программа записывает принятые данные, до прихода «!!!» – что будет являться признаком конца строки.
Программа на VisualBasic отправляет строку, введенную пользователем через UART, при этом дописывая в конце «!!!». Также программа подсказывает, что максимальное число символов, которые может корректно вывести дисплей, равняется 16.[5]
Прграмма на С |
Программа на VisualBasic |
sbit LCD_RS at PORTB2_bit; sbit LCD_EN at PORTB3_bit; sbit LCD_D7 at PORTB4_bit; sbit LCD_D6 at PORTB5_bit; sbit LCD_D5 at PORTB6_bit; sbit LCD_D4 at PORTB7_bit;
sbit LCD_RS_Direction at DDB2_bit; sbit LCD_EN_Direction at DDB3_bit; sbit LCD_D7_Direction at DDB4_bit; sbit LCD_D6_Direction at DDB5_bit; sbit LCD_D5_Direction at DDB6_bit; sbit LCD_D4_Direction at DDB7_bit; int i,pos; char text[20]; void main() { LCD_Init(); LCD_Cmd(_LCD_CURSOR_OFF); UART1_Init(9600); while (1) { if (UART1_Data_Ready() == 1) { UART1_Read_Text(text, "!!!", 255); Lcd_Cmd(_LCD_CLEAR); LCD_Out(1,1,text); text[0]='\0'; } }} |
Public Class Form1
Private Sub ComboBox1_
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click SerialPort1.PortName = "COM2" SerialPort1.Open() Label4.ForeColor = Color.Green Label4.Text = "Connected" End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click SerialPort1.Write(TextBox1. SerialPort1.Write("!!!") End Sub
Private Sub TextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged
If (Len(TextBox1.Text) > 16) Then Label2.ForeColor = Color.Red Else Label2.ForeColor = Color.Black End If Label2.Text = Len(TextBox1.Text) End Sub
Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click SerialPort1.Close() Label4.ForeColor = Color.Red Label4.Text = "Disconnected" End Sub
End Class |
С помощью программы VSPE создадим виртуальную пару COM-портов (COM1 и COM2). К порту COM1 подключим микроконтроллер, а к COM2 будет подключаться пользователь.
Теперь осталось создать проект в Proteus, не забыв установить частоту 9600.
Проверим правильность работы всех программ:
Информация о работе Проектирование систем на базе микроконтроллера AVR