//******************************************************************************************************************
/*
实验接线:
8254:
片选信号CS接Y0;GATE0、GATE1级联接+5V;CLK0接1MHz;CLK1接OUT0;
OUT1接k5(进行8254的方波显示);
8255:
片选信号CS接Y1;A口作为输出用排线接LED灯;PB0、PB1、PB2作为输入分别接K0、K1、K2;
中断:
IR10接OUT1(中断控制程序控制LED灯的闪烁变化);
*/
//******************************************************************************************************************
//8255模块的设置
void init(void);//初始化
void ISR(void);
int i=0,j=0;
const unsigned short
Port8255Base = 0x288;
const unsigned char
ControlWord8255 = 0x82;
void init8255(void);// 8255初始化
//******************************************************************************************************************
//关于8254模块的设置
//通道0: 控制字00110110 -> 36H,即0x36,CLK0=1MHz,OUT0=0.01s,初值=F(clk)*T(out) 初始值:COUNT0=10000
//通道1: 控制字01110110 -> 76H,即0x76,CLK1=OUT0,初值=T1(out)/T1(clk)
//当OUT1=0.5s,k3=0,k2=0,k0=1,1 初始值:COUNT1=50
//当OUT1=1.0s,k3=0,k2=1,k0=0,2 初始值:COUNT1=100
//当OUT1=1.5s,k3=1,k2=0,k0=0,4 初始值:COUNT1=150
void init8254(void);// 8254初始化
const unsigned short
Port8254Base = 0x280, //计数器1端口地址为p8254Base+1,端口地址为p8254Base+3.
counter0=10000;
const unsigned char
ControlWord8254ch0 = 0x36, ControlWord8254ch1 = 0x76;
unsigned short
counter1=100;//计数器初值
byte pData;
unsigned char pdata=0x80;
bool flag=true;
//******************************************************************************************************************
//主函数
void main()
{
init();
init8254();// 8254初始化
init8255();//8255初始化
printf("\n start...\n");
while (!_kbhit())
{
PortReadByte(Port8255Base + 1, &pData);
//写入计数器1的初始值
if(pData==1){
//k0为1的情况,k2k1k0=001,即时间间隔为0.5秒
counter1=50;
PortWriteByte(Port8254Base+1 , counter1%256); // 写计数器1计数初值低8位
PortWriteByte(Port8254Base+1 , counter1/256); // 写计数器1计数初值高8位
printf("=switch state:%x LED灯点亮间隔0.5秒=\n",pData);
}
if(pData==2){
//k1为1的情况,k2k1k0=010,即时间间隔为1.0秒
counter1=100;
PortWriteByte(Port8254Base+1 , counter1%256); // 写计数器1计数初值低8位
PortWriteByte(Port8254Base+1 , counter1/256); // 写计数器1计数初值高8位
printf("=switch state:%x LED灯点亮间隔1.0秒=\n",pData);
}
if(pData==4){
//k2为1的情况,k2k1k0=100,即时间间隔为1.5秒
counter1=150;
PortWriteByte(Port8254Base+1 , counter1%256); // 写计数器1计数初值低8位
PortWriteByte(Port8254Base+1 , counter1/256); // 写计数器1计数初值高8位
printf("=switch state:%x LED灯点亮间隔1.5秒=\n",pData);
}
sleep(3000);// delay 1s
EnableIntr(); // 开中断,功能等效于汇编语言指令sti
RegisterLocalISREx(ISR,10); // 加载中断服务程
printf("Wait for the switch state change...\n\n");
}
_getch();
printf("\n Press any key over...\n");
//DisableIntr(); // 开中断,功能等效于汇编语言指令cli
Cleanup();
}
//中断服务程序,实现跑马灯的流水
void ISR(void)
{
if(flag)
{
_asm
{
ror pdata,1 //循环右移指令
}
}
else
{
_asm
{
rol pdata,1 //循环左移指令
}
}
j++;
if(j==7)
{
flag = false;
}
if(j==14){
flag = true;
j=0;
}
PortWriteByte(Port8255Base,pdata);
}
//机箱的初始化
void init(void)
{
if(!Startup()) // 加载实验平台I/O驱动程序
{
printf("\n\n ERROR: Open Device Error!请打开实验箱电源\n");
_getch();
exit(0); // return to Windows
}
}
//8254初始化
void init8254(void)
{
PortWriteByte(Port8254Base + 3, ControlWord8254ch0); // 写计数器0控制字
PortWriteByte(Port8254Base + 3, ControlWord8254ch1); // 写计数器1控制字
PortWriteByte(Port8254Base , counter0%256); // 写计数器0计数初值低8位
PortWriteByte(Port8254Base , counter0/256); // 写计数器0计数初值高8位
}
//8255初始化
void init8255(void)
{
PortWriteByte(Port8255Base + 3, ControlWord8255); // 写8255控制字
PortWriteByte(Port8255Base,pdata);
}
您好,我是有问必答小助手,您的问题已经有小伙伴解答了,您看下是否解决,可以追评进行沟通哦~
如果有您比较满意的答案 / 帮您提供解决思路的答案,可以点击【采纳】按钮,给回答的小伙伴一些鼓励哦~~
ps:问答VIP仅需29元,即可享受5次/月 有问必答服务,了解详情>>>https://vip.csdn.net/askvip?utm_source=1146287632