>백엔드 개발 >C#.Net 튜토리얼 >C 언어 노트 - C 언어 기반의 흐르는 물 티커

C 언어 노트 - C 언어 기반의 흐르는 물 티커

little bottle
little bottle앞으로
2019-04-10 13:56:054814검색

오늘 대학교 2학년 때 티커를 배우던 중 문득 생각났어요. 그때 코드를 하나씩 입력해서 드디어 티커 상태를 실행했던 기억이 나네요. 엔터티의 코드는 정말 즐겁습니다. 더 이상 고민하지 않고 천막 제작 과정을 공유하겠습니다.

1. 질문:

Marquee # 🎜🎜#

(1) 기본 요구 사항

8254 정확한 타이밍을 사용하면 LED 조명 규칙은 LED8- LED1, 각 LED의 점등 시간 간격은 논리 레벨 스위치 K1, K2 및 K3에 의해 선택됩니다. K1의 시간 간격은 0.5S, K2의 시간 간격은 1.0S, K3의 시간 간격은 1.5S입니다. 호스트 키보드에서 아무 키나 누르면 프레젠테이션을 중지합니다.

(2) 디자인 팁

A 포트를 사용하여 8255 LED 조명을 연결하고, B 포트에 논리 레벨 스위치 K1, K2 및 K3을 연결합니다. 조명 제어는 8254의 인터럽트 서비스 프로그램에서 완료된다. 메인 프로그램은 스위치 변경을 감지해 LED 조명이 켜지는 시간 간격을 변경한다.

(3) 추가 설계 요구 사항

LED 조명 패턴은 LED8-LED1-LED8이 됩니다 #🎜 ㅋㅋㅋ 🎜# 2. 분석:

기본 원리 설계

1단계: 8255는 B 포트를 사용하여 모드 0에서 작동하고 입력을 수행하며 스위치를 얻습니다. (참고: 코스 설정 작업을 용이하게 하기 위해 K2, K1, K0을 사용하여 K3, K2, K1을 대체했으며 구현 요구 사항은 정확히 동일합니다. ) K2K1K0의 값에는 여기에 세 가지 값이 있습니다. 이진 인코딩에서는 100,010,001이고 십진수에서는 4,2,1이며 LED가 켜질 때 1.5초, 1.0초, 0.5초의 시간 간격에 해당합니다. 조명이 켜져 있습니다.

# 🎜 🎜#

2단계: 8254는 작업 모드 3을 채택하여 고정 주파수 구형파를 생성하여 인터럽트 서비스 루틴을 지속적으로 트리거합니다. 메인 프로그램에서 8255의 포트 B의 입력 값을 얻고 입력 값에 따라 8254의 카운터 1에 해당 초기 값을 쓰고 OUT1 끝에서 고정 주파수 구형파 신호를 얻습니다. 여기서는 해당 K7을 연결합니다. 램프는 구형파의 발생을 검증하는 데 사용되며 구형파의 주파수는 램프가 깜박이는 빈도로 대략적으로 판단할 수 있으며 이는 1.5s, 1.0s, 0.5s의 시간 간격에 해당합니다.


# 🎜 🎜#3단계: 8254에서 생성된 구형파 신호 출력은 인터럽트 인터페이스 IR10에 연결됩니다. 이는 구형파 신호의 주파수를 사용하여 특정 시간 간격으로 인터럽트 서비스 프로그램을 시작하는 데 사용됩니다.

4단계: 방형파 주파수 8254에 따라 일정 시간 간격 내에 인터럽트 서비스 프로그램이 로드되어 실행됩니다. 인터럽트 서비스 프로그램에서 8255 포트 A의 출력은 LED7-LED0의 깜박이는 변화를 제어하기 위해 변경됩니다. 즉, 윤곽을 실현합니다.


# 🎜 🎜#
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);
}

【추천 강좌:
C 동영상 튜토리얼

위 내용은 C 언어 노트 - C 언어 기반의 흐르는 물 티커의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 csdn.net에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제