📄 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 + -