⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 340_ad.c

📁 本程序是基于c8051f340对电位器产生的电压值进行采样,可以在寄存器观察AD的 也可以通过LCD将值显示出来
💻 C
字号:
/********************************************************************
例程说明,本程序是对电位器产生的电压值进行采样,可以在寄存器观察AD的
也可以通过LCD将值显示出来,由于LV595芯片片选引脚与以太网控制芯片CP2200
中断引脚复用因些在此例程中加入了将CP2200芯片中断关闭的代码。还要在建立
工程文件时将CP220X_REG.C文件包含到工程中.
********************************************************************/

#include "C8051F340.h"
#include "CP220x_REG.h"

#define uchar unsigned char
#define uint  unsigned int 
#define  BASE_ADDRESS   0x10
#define EMIF_TIMING	0x9E 

sfr16 TMR2RL   = 0xca;                 
sfr16 TMR2     = 0xcc;                 
sbit LcdCs=P0^3;
sbit led=P2^4;
bit SPI_BUSY;


uchar xdata virt_port;
uchar xdata discode;//开关显示、光标、闪烁的命令字暂存单元
uint Count1ms;									
uint temp,ams,temp_l;						   // 存储ADC的变量
uchar xdata tab1[16]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44
                            ,0x45,0x46};
void ADC0_Init(void);                  //ADC初始化
void Timer2_Init(void);				   //定时器初始化
void Delay(void);					   //延时程序
void PORT_Init(void);				   //端口初始化
void delay(uint timer);
void writelcd(uchar spi_data);
void writecode(uchar ins);
void writedata(uchar d);
void lcdinit();
void lcdchar (void);
void lcdaddr(uchar DDRAM);
void cursoropen(uchar position);//开光标,关闪烁
void displayopen(void);			//开显示,光标、闪烁不变
void ether_reset_low();
void ether_reset_high (void);
void Delay1ms(uint T);
void EMIF_Init (void);
void SPI_Init();
/*********************************************************************/
// 主程序
/*********************************************************************/
void main()
{  	 
    uint j;
	PCA0MD   &= ~0x40;                 //关闭看门狗
    OSCICN |= 0x03;                    //使用内部12M晶振			   
	ADC0_Init();					   //ADC初始化
    Timer2_Init();					   //定时器初始化
    PORT_Init();					   //端口初始化
	EMIF_Init ();
    ether_reset_low();
    for(j=0;j<5000;j++);
    ether_reset_high ();
    INT0EN = 0x00;                         
    INT1EN = 0x00;
    SPI_Init();
	lcdinit();
    IE = 0x40;
    EA=1;							   //开中断
  while(1)
  { 	lcdinit();
  	lcdchar();
  }                                   //取值此处加显示

}
/*********************************************************************/
// 延时程序
/*********************************************************************
void Delay(void)
{
   int x;
   for(x = 0;x < 500;x)
      x++;
}
/*********************************************************************/
// 定时器2中断程序
/*********************************************************************/
void Timer2_ISR(void) interrupt 5
{
  
   TF2H = 0;                           // 清除定时器2的中断标志
}
/*********************************************************************/
// ADC初始化程序
/*********************************************************************/
void ADC0_Init(void)
{
   REF0CN  = 0x0F;                     //使用内部参考电压VREF
   AMX0P = 0x04;                       // P2.5为输入端
   AMX0N = 0x1F;                       // 单端输入

   ADC0CF  = 0xFC;                     // 采样值右对齐,如左对齐其值为FC

   ADC0CN  = 0xC2;                     //采用定时器2溢出后3个SAR时钟开转换
                                       // 这时MCU功耗比较低

   EIE1   |= 0x08;                     //使能ADC中断
}

 /*********************************************************************/
// ADC中断程序
/*********************************************************************/
void ADC0_ConvComplete_ISR(void) interrupt 10
{
      temp= ADC0H;						  //高字节
      ams=ADC0L;						  //低字节
	//  temp_l=temp<<8+ams;
      AD0INT = 0;						  //清中断
}
/*********************************************************************/
// 端口初始化程序
/*********************************************************************/
void PORT_Init(void)
{
   P2MDIN   = 0xDF;                    // P2.5 为模拟输入
   P2SKIP   = 0x20;                    // P2.5 跳过
   XBR0     = 0x02;
   XBR1     = 0x40;                    // 允许交叉开关
   P0MDOUT  =0xff;
   P1MDOUT |= 0xD8;                    // /WR and /RD are push-pull   P3MDOUT |= 0xFF;   P4MDOUT |= 0xFF;
}

/*********************************************************************/
// 定时器2初始化程序
/*********************************************************************/
void Timer2_Init(void)
{
   TMR2CN  = 0x00;                     //清定时器2标志

   CKCON  &= ~0xF0;                    //选择时基
   TMR2RL  = 0;                        // 重载值
   TMR2    = 0xffff;                   // 

   ET2     = 1;                        // 使能定时器2 中断
   TR2     = 1;                        // 开启定时器2
}
             
void delay1us(void)
{
	uchar xdata i;
	for(i=10;i>0;i--);
} 

void SPI_Init()
{
    SPI0CFG   = 0x70;
    SPI0CN    = 0x01;
    SPI0CKR   = 0x3B;
  

} 

void writelcd(uchar spi_data)	   //向LV595写数据以SPI方式
{

 	uint xdata i,j;
 	for(i=0;i<3;i++)
	LcdCs=0;
	SPI_BUSY=1;
	delay1us();
	SPI0DAT=spi_data;
	
     for(j=0;j<500;j++)
		{
	   if(!SPI_BUSY)break;
		} 
	delay1us();
	LcdCs=1;
	delay1us();
 	delay1us();
	delay1us();
	delay1us();
	delay1us();
	delay1us();
	delay1us();
	for(j=0;j<5000;j++);

}

 void writecode(uchar ins)				    //向液晶控制模块写命令
     {
      uchar xdata t;
	  uint xdata j;
	
	  for(j=0;j<500;j++);	
	  virt_port|=ins&0xf0;					//取高字节向1602写数据 
	  writelcd(virt_port);					//先写高4位后再写低4位 这是在选择四个数据线的时候
     
	  virt_port|=0x08;						  
	  writelcd(virt_port);					//使能E脚为高电平
      virt_port&=~0x08;					
	  writelcd(virt_port);					//使能E脚为低电平

      t=ins<<4;             
      virt_port|=t&0xf0;          			//取低字节向1602写数据
	  writelcd(virt_port);
      virt_port|=0x08;						//使能E脚为高电平
	  writelcd(virt_port);
      virt_port&=~0x08;					    //使能E脚为低电平
	  writelcd(virt_port);
      virt_port=0;
	  writelcd(virt_port);
     }

void writedata(uchar d)					   //写数据到1602
     {
      uchar xdata i,t;
	  uint xdata j;
	  
      for(j=0;j<500;j++);		
      virt_port|=0x02;					   //光标返回指令
	  writelcd(virt_port);
      virt_port|=d&0xf0;				   //取高字节数据给数据寄存器
	  writelcd(virt_port);
      virt_port|=0x08;                     //使能E脚为高电平
	  writelcd(virt_port);
      virt_port&=0xf7;      			   //使能E脚为低电平
	  writelcd(virt_port);
      virt_port&=0x07;					   //设置光标右移,文字也右移
      writelcd(virt_port);
	       
      t=d&0x0f;
      virt_port|=t<<4;					   //取低字节数据给数据寄存器
	  writelcd(virt_port);

	  virt_port|=0x08;      			   //使能E脚为高电平
	  writelcd(virt_port);
      for(i=3;i>0;i--); 
      virt_port&=0xf7;                     //使能E脚为低电平
	  writelcd(virt_port);
      virt_port=0;						   //数据清零
	  writelcd(virt_port);
    }
 void lcdchar (void)
 {
//     uint xdata j,k;
	 uchar a,b,c,d;
     temp=temp<<8;
	 temp_l=temp+ams;
	 temp_l=temp_l>>4;
  	 a=temp_l/1000;d=temp_l%1000;    
     writedata(tab1[a]);
	 b=d/100;d=d%100;
	 writedata(tab1[b]);
	 c=d/10; d=d%10;
	 writedata(tab1[c]);
	 writedata(tab1[d]);
      
    	  
   
   
}
 
void lcdinit()
{
     uint xdata i;
	
      virt_port=0x00;
	  writelcd(virt_port);	     //RS脚为零写指令寄存器	 RW为低电平
      virt_port|=0x08;     	     //使能脚E=1
	  writelcd(virt_port);
 	  virt_port&=0xf7;    		 //使E=0使能脚发生跳变高--低
	  writelcd(virt_port);
	  for(i=1000;i>0;i--);	     //3次延时,重要!
	  for(i=8000;i>0;i--);		 //用延时代替查询	  

    
      virt_port=0;				 //写入20码,设置为4位总线方式,非常重要!!!!!
	  writelcd(virt_port);
      virt_port|=0x20;			 //只写高字节
	  writelcd(virt_port);
      virt_port|=0x08;           //E=1
	  writelcd(virt_port);
	  for(i=20;i>0;i--);		 //使命令执行
      virt_port&=0xf7;           //E=0
	  writelcd(virt_port);
	  for(i=10;i>0;i--);
      virt_port=0;
	  writelcd(virt_port);
	 
	 

      writecode(0x38);	    	//设两行显示,4线方式5*10字符显示
      for(i=50;i>0;i--);
	    writecode(0x06);			//光标右移
      for(i=50;i>0;i--);
	 
	  
	  writecode(0x0c);		    //开显示指令
      for(i=50;i>0;i--);
      
	 
      writecode(0x02);			//光标返回指令
      for(i=50;i>0;i--);
	   
    
	 
	  writecode(0x01);			//清屏指令
	  for(i=50;i>0;i--);
}
void spi_isr(void) interrupt 6 
{
	if(SPIF)		
		{
		SPIF=0;
		SPI_BUSY=0;
		}
		

	if(WCOL)
		{
		WCOL=0;
		}
}
  
void ether_reset_low(){   P1 &= ~0x01;               // Pull reset low}void ether_reset_high (void){   P1 |= 0x01;               // Allow /RST to rise   while(!(P1 & 0x01));      // Wait for /RST to go high}
void EMIF_Init (void){   EMI0CF = 0x1B;             // non-muxed mode; split mode                              // with bank select   EMI0TC = EMIF_TIMING;      // This constant may be modified                              // according to SYSCLK to meet the                              // timing requirements for the CP2200   EMI0CN = BASE_ADDRESS;     // Page of XRAM accessed by EMIF}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -