?? m16t1.c
字號:
/*******************************************************************
實驗十一
實驗名稱: 定時器1中斷實驗
實驗目的: 學習AVR單片機的定時器功能
實驗現象: 定時器每秒加一,0到255循環,通過數碼管顯示計數值
環 境: ICCAVR6.31A
設 計 者: shinea8868
說 明: 部分程序原型源自網絡,經本人修改調試可用,請尊重知識產權,如
作商業用途請保留本段文字
完成日期: 2007年4月10日
*******************************************************************/
#include <iom16v.h>
#include <macros.h>
#include "..\ICC_H\SOFTWARE.h"
uchar TimerCnt = 0; //定時器1計數個數
uchar disp[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
/*-----------------------------------------------------------------
延時程序計算方法
計數個數j = 延時時間/6*晶振頻率 - 1
函數名稱: void DelayMs(uchar i)
函數功能: 毫秒延時
參 數:
返 回 值: 無
-----------------------------------------------------------------*/
void DelayMs(uchar i)
{
uchar j;
while(i--)
{
j = 167;//1mhz 1ms延時
while(j--);
}
}
/*-----------------------------------------------------------------
函數名稱: void SPIMasterInit(void)
函數功能: SPI初始化為主機
參 數:
返 回 值: 無
-----------------------------------------------------------------*/
void SPIMasterInit(void)
{
// MOSI,MISO,SCK等都需要設計的數據方向定義
DDRB |= (1<<PB5) | (1<<PB7); // 設置MOSI 和SCK 為輸出,其他為輸入 M16
// DDRB |= (1<<PB2) | (1<<PB3); // 設置MOSI 和SCK 為輸出,其他為輸入 M64
// SPI控制寄存器
// SPIE SPE DORD MSTR CPOL CPHA SPR1 SPR0
// SPIE 中斷使能 SPE SPI使能 DORD 數據次序 1為LSB首先發送,0為MSB首先發送
// MSTR 主從選擇 1為主,0為從MSTR置位時選擇主機模式,否則為從機.如果MSTR為"1",
// SS配置為輸入,但被拉低,則MSTR 被清零,寄存器SPSR 的SPIF 置位.用戶必須重新設置
// MSTR 進入主機模式。
// CPOL: 時鐘極性見ATMEGA16L(中文)P130
// CPHA: 時鐘相位
// SPR1, SPR0: SPI 時鐘速率選擇1 與0 SPR1 和SPR0 對從機沒有影響。
// 使能SPI 主機模式,設置時鐘速率為fck/128 */
SPCR = (1<<SPE) | (1<<MSTR) | (1<<SPR1) | (1<<SPR0);
}
/*-----------------------------------------------------------------
函數名稱: void SPIMasterTransmit(unsigned char i)
函數功能: SPI數據發送
參 數:
返 回 值: 無
-----------------------------------------------------------------*/
void SPIMasterTransmit(uchar TranData)
{
SPDR = TranData; // 啟動數據傳輸
while (!(SPSR & (1<<SPIF))); // 等待傳輸結束
}
/*-----------------------------------------------------------------
函數名稱: void SPI595Out(unsigned char i)
函數功能: 通過74HC595輸出數據
參 數:
返 回 值: 無
-----------------------------------------------------------------*/
void SPI595Out(unsigned char i)
{
PORTB &= ~(1 << 4); //準備鎖存
SPIMasterTransmit(i);
PORTB |= (1 << 4); //鎖存數據
}
/*-----------------------------------------------------------------
函數名稱: void Timer1Init(void)
函數功能: 定時器1初始化 256預分頻 定時一秒
參 數:
返 回 值: 無
-----------------------------------------------------------------*/
void Timer1Init(void)
{
TCCR1B = 0x00; //關定時器
TCNT1H = 0xF0; //設置定時初值
TCNT1L = 0xBE;
OCR1AH = 0x0F;
OCR1AL = 0x42;
OCR1BH = 0x0F;
OCR1BL = 0x42;
ICR1H = 0x0F;
ICR1L = 0x42;
TCCR1A = 0x00;
TCCR1B = 0x04; //開始計數
}
#pragma interrupt_handler timer1_ovf_isr:9
void timer1_ovf_isr(void)
{
TCNT1H = 0xF0; //重新裝載計數值
TCNT1L = 0xBE;
TimerCnt++;
}
/*-----------------------------------------------------------------
函數名稱: void InitDevices(void)
函數功能: 初始化各種信息
參 數:
返 回 值: 無
-----------------------------------------------------------------*/
void InitDevices(void)
{
CLI(); //關全部中斷
SPIMasterInit(); //SPI初始化為主機
Timer1Init();
TIMSK = 0x04; //timer interrupt sources
SEI(); //開中斷
}
void main(void)
{
uchar temp;
DDRA = 0x00; //方向輸入
PORTA = 0xFF; //打開上拉
DDRB = 0xFF; //方向輸出
PORTB = 0xF0; //電平設置
DDRC = 0x00;
PORTC = 0xFF;
DDRD = 0xFF;
PORTD = 0xFF;
InitDevices();
while (1)
{
if( TimerCnt > 9)
{
if( TimerCnt > 99)
{
DDRB = 0xff;
PORTB = 0xff;
temp = TimerCnt / 100;
SPI595Out(disp[temp]);
PORTB = 0xfb;
DelayMs(1);
PORTB = 0xff;
temp = TimerCnt%100/10;
SPI595Out(disp[temp]);
PORTB = 0xfd;
DelayMs(1);
PORTB = 0xff;
temp = TimerCnt%10;
SPI595Out(disp[temp]);
PORTB = 0xfe;
}
else
{
DDRB = 0xff;
PORTB = 0xff;
temp = TimerCnt/10;
SPI595Out(disp[temp]);
PORTB = 0xfd;
DelayMs(1);
PORTB = 0xff;
temp = TimerCnt%10;
SPI595Out(disp[temp]);
PORTB = 0xfe;
}
}
else
{
DDRB = 0xff;
PORTB = 0xfe;
SPI595Out(disp[TimerCnt]);
}
DelayMs(1);
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -