论文首页哲学论文经济论文法学论文教育论文文学论文历史论文理学论文工学论文医学论文管理论文艺术论文 |
利用CSBX-1A实验板上的CPLD和单片机,可以做很多实验,以下举一个例子。1、功能描述 单片机的P1.0、P1.1和P1.2与CPLD相应引脚相连,本例是将CPLD作为一个串行接口,相当于两片74HC595串接,由单片机将数据以串行方式发送过来,CPLD读出数据并在CPLD的显示器上显示出来。 使用单片机智能模块中的Up和Down键,分别按下这两个键可使预定的数据增加或减少,该数据显示在智能模块的LED显示器上,同时以串行方式发送往CPLD。2、单片机程序
***************************************************************;
* 平凡单片机工作室;* ;* (c) Copyright 2004,Mcustudio,JiangSu,LiYang;* All Rights Reserved;* key.c;* 编程:周坚;* 用于CPLD实验板;* 定时中断实现显示的程序;* 按Up键加1,按Down键减1;* 数据同时通过串行方式发送往CPLD***************************************************************/
#include <intrins.h>#include "reg52.h"#define uchar unsigned char#define uint unsigned int uchar Xnjz; //虚拟键值uint Data=100;sbit KeyShift=P3^5; //移位键sbit KeyUp=P3^6; //Up键sbit KeyDown=P3^7; //Down键uchar code BitTab[]={0x01,0x02,0x04,0x08,0x10,0x20};uchar code DispTab[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E,0xFF};uchar Count=0; //计数器,显示程序通过它得知现正显示哪个数码管uchar DispBuf[6]={1,2,3,4,5,6}; //6字节的显示缓冲区#define Hidden 0x10; //消隐码////定义用于单片机显示器的引脚sbit Dat=P3^2; //sbit Clk=P3^3;sbit RCK=P3^4; // //定义用于CPLD的串行接口引脚sbit cDat=P1^0;sbit cRck=P1^1;sbit cClk=P1^2;/* 发送往显示 * oid SendData(unsigned char SendDat){ unsigned char i;for(i=0;i<8;i++){ if((SendDat&0x80)==0)Dat=0;elseDat=1;_nop_();Clk=0;_nop_(); Clk=1;SendDat=SendDat<<1;}}/* 发送往CPLD * oid SendToCpld(unsigned char SendDat){ unsigned char i;for(i=0;i<8;i++){ if((SendDat&0x80)==0)cDat=0;elsecDat=1;_nop_();cClk=0;_nop_(); cClk=1;SendDat=SendDat<<1;}}void Timer0() interrupt 1{ uchar tBit=0,tSeg=0;TH0=(65536-5000)/256;TL0=(65536-5000)%256; //定时时间为2500个周期,采用stc89c52rc单片机,倍速tBit=BitTab[Count]; //取位值tSeg=DispBuf[Count]; //取出待显示的数 tSeg=DispTab[tSeg]; //取字形码RCK=0;SendData(tSeg); //段驱动SendData(tBit); //位驱动RCK=1;Count++;if(Count==6)Count=0; }void mDelay(unsigned int Delay) { unsigned int i;for(;Delay>0;Delay--){ for(i=0;i<124;i++){;}}}void KeyProcess(uchar KeyVal){switch(KeyVal){ case 0xfb: //移位键break; //在本程序中没有什么用处case 0xfd: //Up键{ if(Data<9999)Data++;break; } case 0xfe: //Down键 { if(Data>0)Data--; break; }}}//预处理键值,将键位移入虚拟键值中void PreKey(){ uchar Ktmp=0;KeyShift=1; //移位键KeyUp=1; //Up键KeyDown=1; //Down键Ktmp=Ktmp<<1;if(KeyShift)Ktmp|=0x01;Ktmp=Ktmp<<1;if(KeyUp)Ktmp|=0x01;Ktmp=Ktmp<<1;if(KeyDown)Ktmp|=0x01;Xnjz=Ktmp; //虚拟键值}void Key() /*键处理*/{ uchar tmp1,tmp2;PreKey();tmp1=Xnjz|0xf8; if(tmp1==0xff) //无键按下return;else{ mDelay(10); //延时10msPreKey();tmp1=Xnjz|0xf8;if(tmp1==0xff)return;else{ tmp2=tmp1;for(;;){ PreKey();tmp1=Xnjz|0xf8;if(tmp1==0xff)break;}KeyProcess(tmp2);}}}void main(){ uint tmp;TMOD=0x11;TH0=(65536-5000)/256;TL0=(65536-5000)%256; //定时时间为2500个周期TR0=1;EA=1;ET0=1;for(;;){ Key();tmp=Data;DispBuf[5]=tmp%10;tmp/=10;DispBuf[4]=tmp%10;tmp/=10;DispBuf[3]=tmp%10;tmp/=10;DispBuf[2]=tmp%10;DispBuf[1]=Hidden;DispBuf[0]=Hidden;cRck=1;SendToCpld(Data/256);SendToCpld(Data%256);cRck=0;} }3、CPLD的Verilog程序//说明:用于csbx-1A实验板//功能:接收单片机通过串行方式发送过来的数据并以十六进制形式显示在4位LED上//与之配套的单片机程序为Keys.c//状态:单片机程序及CPLD程序均已通过调试module serial(clock,seg,sl,iData,Sclk,Rclk); input iData; // serial input Data Pin Pin1 P1.0 input Rclk; / rial Enable Clock Pin Pin2 P1.1 input Sclk; / rial input Clock Pin Pin3 P1.2 input clock; output [7:0] seg; output [3:0] sl; reg [7:0] seg_reg; reg [3:0] sl_reg; reg [3:0] disp_dat; reg [36:0] count; reg [16:0] reciveDat,reciveDat0; Rclk)reciveDat=reciveDat0; Sclk)beginreciveDat0=reciveDat0<<1;reciveDat0[0]=iData;endalways@(posedge clock)begin count=count+1; //计数器]) //定义显示数据触发事件begin case(count[14:13]) //选择扫描显示数据2'h0:disp_dat=reciveDat[15:12]; //显示个位数据2'h1:disp_dat=reciveDat[11:8]; 2'h2:disp_dat=reciveDat[7:4]; 2'h3:disp_dat=reciveDat[3:0]; //显示百位数据 endcase case(count[14:13]) //选择数码管显示位2'h0:sl_reg=4'b1110; //选择个位数码管2'h1:sl_reg=4'b1101;2'h2:sl_reg=4'b1011;2'h3:sl_reg=4'b0111;endcase end ) begin case(disp_dat)4'h0: seg_reg = 8'hc0; //显示04'h1: seg_reg = 8'hf9; //显示14'h2: seg_reg = 8'ha4; //显示24'h3: seg_reg = 8'hb0; //显示34'h4: seg_reg = 8'h99; //显示44'h5: seg_reg = 8'h92; //显示54'h6: seg_reg = 8'h82; //显示64'h7: seg_reg = 8'hf8; //显示74'h8: seg_reg = 8'h80; //显示84'h9: seg_reg = 8'h90; //显示94'ha: seg_reg = 8'h88; //显示a4'hb: seg_reg = 8'h83; //显示b4'hc: seg_reg = 8'hc6; //显示c4'hd: seg_reg = 8'ha1; //显示d4'he: seg_reg = 8'h86; //显示e4'hf: seg_reg = 8'h8e; //显示fendcaseendassign seg=seg_reg;assign sl=sl_reg;endmodule4、程序实现