微机原理8254/8255实现花式跑马灯

K 2 K 1 K 0 K_2 K_1 K_0 K2K1K0进行控制,采用if-else结构对高位进行屏蔽

K 2 K 1 K 0 = 111 ∣ K 2 K 1 K 0 = 000 {K_2}{K_1}{K_0}=111|{K_2}{K_1}{K_0}=000 K2K1K0=111∣K2K1K0=000时,进行花式跑马灯
K 2 K 1 K 0 = x x 1 {K_2}{K_1}{K_0}=xx1 K2K1K0=xx1时,延时500ms
K 2 K 1 K 0 = x 10 {K_2}{K_1}{K_0}=x10 K2K1K0=x10时,延时1000ms
K 2 K 1 K 0 = 100 {K_2}{K_1}{K_0}=100 K2K1K0=100时,延时1500ms

音乐为两只老虎

/*

  实验接线: 8254:
				片选信号CS接Y0;GATE0、GATE1级联接+5V;CLK0接1MHz;CLK1接OUT0;
				OUT1接k5(进行8254的方波显示);
				OUT2接喇叭 GATE2接PC0 CLK2接1M
			 8255:
				片选信号CS接Y1;A口作为输出用排线接LED灯;PB0、PB1、PB2作为输入分别接K0、K1、K2;
			 中断:
				IR10接OUT1(中断控制程序控制LED灯的闪烁变化);
			
  
  
			 8255 端口地址为288~28B
				  控制字为 0x82
				   
			 8254
			 通道0:控制字00110110 即 36H, CLK0 = 1MHz  OUT0 = 0.01s  
					初值 =  F(clk)*T(out) 即 Count0 = 10000
			 通道1:控制字01110110 即 76H, CLK1 = OUT0
					初值 = T1(out)/T1(clk)

			 //当OUT1 = 500ms, k3 = 0, k2 = 0, k0 = 1, 初始值:COUNT1=50
			 //当OUT1 = 1000ms,k3 = 0, k2 = 1, k0 = 0, 初始值:COUNT1=100
			 //当OUT1 = 1500ms,k3 = 1, k2 = 0, k0 = 0, 初始值:COUNT1=150

			
*/
#include "interface.h"
#include <stdlib.h>
void init8255(void);//8255初始化
void init8254(void);
void init(void);
void ISR(void);
void Bigbang(void);
const unsigned short Port8255Base = 0x288;
const unsigned char ControlWord8255 = 0x82;//8255控制字
unsigned char pData = 0x80;
unsigned char gData = 0x80;
const unsigned short Port8254Base = 0x280;
const unsigned short counter0 = 10000;
const unsigned char ControlWord8254ch0 = 0x36, ControlWord8254ch1 = 0x76, ControlWord8254ch2 = 0xB6 ; //8254控制字

const unsigned long Fin=1000000; // 输入频率1MHz


const unsigned short frq1[] = {262, 294, 330, 262, 294, 330, 262, 330, 349, 392,
											392, 440, 392, 349, 330, 262, 392, 440, 392, 349,
											330, 262, 294, 196, 262, 294, 196, 262};

const unsigned short beat1[] = {25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 
											50, 25, 25, 50, 12, 12, 12, 12, 25, 25,
											12, 12, 12, 12, 25, 25, 25, 25, 50, 25,
											25, 50};


unsigned short counter1 = 0;
int timerConst1[50];
int timerConst2[50];
int id = 0;
int flag = 1;
void main()
{
	init();
	init8255();
	init8254();
	printf("\n   软件延时跑马灯实验\n   Press any key to qiut ...\n");

	for(int i=27;i>=0;i-- )
	{
		timerConst1[i]=Fin/frq1[i]; // 计数器初值
		timerConst2[i]=Fin/frq2[i]; // 计数器初值
	}

	while (!_kbhit())
	{
		PortReadByte(Port8255Base + 1, &pData); //读入B口数据

		if(pData == 7)
		{
			Bigbang();
		}
		else if (pData == 1)
		{
			counter1 = 50;
			PortWriteByte(Port8254Base + 1, counter1 % 256);
			PortWriteByte(Port8254Base + 1, counter1 / 256);
			printf("延时500ms\n");
		}
		else if (pData == 2)
		{
			counter1 = 100;
			PortWriteByte(Port8254Base + 1, counter1 % 256);
			PortWriteByte(Port8254Base + 1, counter1 / 256);
			printf("延时1000ms\n");
		}
		else if (pData == 4)
		{
			counter1 = 150;
			PortWriteByte(Port8254Base + 1, counter1 % 256);
			PortWriteByte(Port8254Base + 1, counter1 / 256);
			printf("延时1500ms\n");
		}
		sleep(3000);
		RegisterLocalISREx(ISR, 10);
		EnableIntr();
	}
	_getch();
	printf("\n请按任意键\n");
	Cleanup();
}

void Bigbang(void)
{
	srand((unsigned)time(NULL));
	//int time[4] = {1500, 1000, 500, 200};
	for(int i = 0; i < 4; i ++ )
	{
		PortWriteByte(Port8255Base, 0xff); // 灯亮
		sleep(500);
		PortWriteByte(Port8255Base, 0); // 灯灭

		PortWriteByte(Port8255Base + 2, 1); // 打开喇叭
		PortWriteByte(Port8254Base + 2, timerConst1[id] % 256);
		PortWriteByte(Port8254Base + 2, timerConst1[id] / 256);
		sleep(beat1[id]);
		id ++;
		id %= 27;
		//PortWriteByte(Port8255Base + 2, 0); // 关闭喇叭
	}
	unsigned char left = 0x80, right = 0x01;
	unsigned char light = left + right;
	while(1)
	{
		PortReadByte(Port8255Base + 1, &pData); //读入B口数据
		if(pData != 7) break;
		light = left + right;
		PortWriteByte(Port8255Base, light); // 灯亮
		int a = rand()%1500;
		a = max(a, 150);
		sleep(500);
		PortWriteByte(Port8255Base, 0); // 灯灭
		left = left >> 1;
		right = right << 1;
		if(left == 1)
		{
			light = left;
			left = right;
			right = light;
			for(int j = 0; j < 4; j ++ )
			{
				PortWriteByte(Port8255Base, 0xff); // 灯亮
				sleep(500);
				PortWriteByte(Port8255Base, 0); // 灯灭

				PortWriteByte(Port8255Base + 2, 1); // 打开喇叭
				PortWriteByte(Port8254Base + 2, timerConst1[id] % 256);
				PortWriteByte(Port8254Base + 2, timerConst1[id] / 256);
				sleep(beat1[id]); 
				id ++;
				id %= 27;
			}
		}

		PortWriteByte(Port8255Base + 2, 1); // 打开喇叭
		PortWriteByte(Port8254Base + 2, timerConst1[id] % 256);
		PortWriteByte(Port8254Base + 2, timerConst1[id] / 256);
		sleep(beat1[id]); 
		id ++;
		id %= 27;
	}


}

void ISR(void)
{
	PortWriteByte(Port8255Base, gData); // 灯亮
	if (flag)
	{
		_asm {
			ror  gData, 1
		}
		if (gData == 1)
		{
			flag = 0;
		}
	}
	else
	{
		_asm {
			rol  gData, 1
		}
		if (gData == 128)
		{
			flag = 1;
		}
	}
	
	PortWriteByte(Port8255Base + 2, 1); // 打开喇叭
	PortWriteByte(Port8254Base + 2, timerConst1[id] % 256);
	PortWriteByte(Port8254Base + 2, timerConst1[id] / 256);
	sleep(beat1[id]); 
	id ++;
	id %= 27;

}


void init(void)
{
	if (!Startup())	// 加载实验平台I/O驱动程序		
	{
		printf("\n\n        ERROR: Open Device Error!请打开实验箱电源\n");
		_getch();
		exit(0); // return to Windows
	}
}

void init8254(void)
{
	PortWriteByte(Port8254Base + 3, ControlWord8254ch0);
	PortWriteByte(Port8254Base + 3, ControlWord8254ch1);
	PortWriteByte(Port8254Base + 3, ControlWord8254ch2);
	PortWriteByte(Port8254Base, counter0 % 256);
	PortWriteByte(Port8254Base, counter0 / 256);
}

void	init8255(void)
{
	PortWriteByte(Port8255Base + 3, ControlWord8255); // 写8255控制字
	PortWriteByte(Port8255Base, 0xff); // 灯亮
	sleep(1000);
	PortWriteByte(Port8255Base, 0); // 灯灭
}
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值