Maison  >  Article  >  développement back-end  >  Notes en langage C - ticker d'eau courante basé sur le langage C

Notes en langage C - ticker d'eau courante basé sur le langage C

little bottle
little bottleavant
2019-04-10 13:56:054745parcourir

Aujourd'hui, je me suis soudainement souvenu que lorsque j'étais en deuxième année à l'université, j'avais découvert le chapiteau. À cette époque, j'avais tapé le code un par un et j'ai finalement exécuté l'état du chapiteau. Je me souviens encore de l'effet final de l'exécution du chapiteau. le code sur l'entité est vraiment agréable. Sans plus attendre, je partagerai avec vous le processus de production du chapiteau.

1. Question :

Chapiteau

(1)Exigences de base

En utilisant 8254 pour une synchronisation précise, le modèle d'éclairage LED est LED8-LED1. L'intervalle de temps d'éclairage de chaque LED est déterminé par les commutateurs de niveau logique K1, K2 et. Sélection K3. L'intervalle de temps de K1 est de 0,5 S, l'intervalle de temps de K2 est de 1,0 S et l'intervalle de temps de K3 est de 1,5 S. Arrête la présentation lorsqu'une touche est enfoncée sur le clavier hôte.

(2) Conseils de conception

Utilisez le port A de 8255 pour connecter la lumière LED et le port B pour connecter le niveau logique interrupteurs K1, K2 et K3 . Le contrôle de la lumière est complété dans le programme de service d'interruption du 8254. Le programme principal détecte le changement de l'interrupteur et modifie l'intervalle de temps d'allumage de la lumière LED.

(3) Autres exigences de conception

Le modèle d'éclairage des LED devient LED8-LED1-LED8


2. Analyse :

Conception des principes de base

Étape 1 : 8255 utilise le port B pour fonctionner en mode 0, effectuer la saisie et obtenir des commutateurs (Remarque : afin de faciliter les opérations de réglage des cours, nous utilisons K2 , K1, K0 remplacent K3, K2, K1 par les mêmes exigences d'implémentation.) La valeur de K2K1K0, il y aura ici trois valeurs, qui sont 100 010 001 en codage binaire, c'est-à-dire 4, 2 et 1 en décimal, correspondant respectivement aux points lumineux LED. Les intervalles de temps d'éclairage sont de 1,5 s, 1,0 s et 0,5 s.


Étape 2 : 8254 adopte le mode de fonctionnement trois , génère une onde carrée à fréquence fixe pour déclencher en continu la routine de service d'interruption. Dans le programme principal, obtenez la valeur d'entrée du port B de 8255, écrivez la valeur initiale correspondante dans le compteur 1 de 8254 en fonction de la valeur d'entrée et obtenez un signal d'onde carrée à fréquence fixe à l'extrémité OUT1. Ici, nous connectons un K7 correspondant. La lampe est utilisée pour vérifier la génération de l'onde carrée et la fréquence de l'onde carrée peut être grossièrement jugée par la fréquence de clignotement de la lampe, qui correspond aux intervalles de temps de 1,5 s, 1,0 s et 0,5 s.


Étape 3 : Sortie du signal d'onde carrée généré par 8254 , Connecté à l'interface d'interruption IR10, il est utilisé pour utiliser la fréquence du signal d'onde carrée pour lancer le programme de service d'interruption à certains intervalles de temps.

Étape 4 : Le programme de service d'interruption est chargé et exécuté dans un certain intervalle de temps en fonction de la fréquence d'onde carrée de 8254. Dans le programme de service d'interruption, la sortie du port A de 8255 est modifiée pour contrôler les changements clignotants de LED7-LED0, c'est-à-dire pour réaliser le chapiteau.


3.

//******************************************************************************************************************
/*
实验接线:
	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);
}
[Cours recommandé :

Tutoriel vidéo C]

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer