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

📄 text22.c

📁 上海交通大学科技创新实验5代码
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <absacc.h>
#include <reg51.h>

/*////////////////////////////*/
/*/			常量定义         /*/
/*////////////////////////////*/

/* 定时器初值 */
#define V_T1   0xfd   /*SCOM  9600 baud,  ! notice: crystal 11.0592MHz */
#define V_TH0   0xee  /*   ~ 5ms ,  ! notice: crystal 11.0592MHz */
#define V_TL0   0x00

/* 数码管段驱动寄存器地址 */
#define ADDR_8SEG	XBYTE[0x2000]

/* 数码管位驱动和指示灯驱动寄存器地址 */
#define ADDR_SEL	XBYTE[0x4000]

/* 单片机输出频率 */				
#define PWM_FREQ	400
#define TOTAL_TIME  (11059200/12/PWM_FREQ)

/* ADC0804的地址 */
#define ADDR_0804  XBYTE[0x6000]

/* 按键 */
sbit KEY1=	P1^0;
sbit KEY2=	P1^1;
sbit KEY3=	P1^2;
sbit KEY4=	P1^3;

/* 输出 */
sbit PWM_OUT= P3^5;

/* 按键采样相同判定个数 */
#define v_keycount 3
#define ADJUST_NUM 3

/*电压采样个数*/
#define AD_SMPL_NUM 20

/*多项式阶数*/
#define V_POLYNOMINAL 2

/*闭环控制延迟因子*/
#define CLC_DELAY	100

/*////////////////////////////*/
/*/			变量定义         /*/
/*////////////////////////////*/

/* 按键状态标志和计数器 */
bit key1_flag;
bit key2_flag;
bit key3_flag;
bit key4_flag;
unsigned char key1_count;
unsigned char key2_count;
unsigned char key3_count;
unsigned char key4_count;

/* 按键当前状态和前一状态 */
bit cur_sample1;
bit pre_sample1;
bit cur_sample2;
bit pre_sample2;
bit cur_sample3;
bit pre_sample3;
bit cur_sample4;
bit pre_sample4; 

/* 数码管位驱动和指示灯驱动信号输出缓存,定义了一个可位寻址的变量 */
unsigned char bdata output_sel;
	sbit led_1 = output_sel^5;
	sbit led_2 = output_sel^6;
	sbit led_3 = output_sel^7;
	sbit led_4 = output_sel^4;

/* 数码管扫描驱动指针,为测试外部存储器(U3 6264),特使用xdata类型 */
unsigned char xdata digi_scaner;

/* 测试用计数值十进制表示,为测试外部存储器(U3 6264),特使用xdata类型 */
unsigned char xdata digi[4];

/*系统输出电压*/
unsigned int volt;	 

/* 单片机输出信号占空比 */
int prop_int;	
float prop_float;

/*设定和显示状态标志*/
unsigned char setting_flag;
bit refresh_flag;
bit change_flag;

/*自动拟合参数*/
unsigned char adjust_count;
unsigned int adjust_Prop[ADJUST_NUM+1];

/*定时器1重装值变量*/
unsigned int hilv_time;
unsigned int lolv_time;
unsigned int hilv_th;
unsigned int hilv_tl;
unsigned int lolv_th;
unsigned int lolv_tl;
bit PWM_flag;

/*pv多项式变量*/
float coe_pv[V_POLYNOMINAL+1];

/*临时贮存用变量*/
unsigned char i,j;

/* 模数转换部分变量定义 */
bit AD_flag;
unsigned char xdata AD_data[AD_SMPL_NUM];
unsigned char AD_ptr;
unsigned int xdata AD_value;
unsigned int xdata AD_require;
int xdata AD_temp;

/* 开\闭环控制变量 */
bit CLC_flag;
unsigned char DelayCounter;

/*////////////////////////////*/
/*/			函数定义         /*/
/*////////////////////////////*/


/**** 7段数码显示译码 
    参数:
		DATA: 需要显示的数字或符号;
	返回值: 7段译码结果 ( D7~0 = PGFEDCBA )
*****/
unsigned char NUMTOSEG7(unsigned char DATA)
{ unsigned char AA;
  switch (DATA)
  { 
	case 0: AA=0xc0;break; /* '0' */
    case 1: AA=0xf9;break; /* '1'and'i' */
    case 2: AA=0xa4;break; /* '2' */
    case 3: AA=0xb0;break; /* '3' */
    case 4: AA=0x99;break; /* '4' */
    case 5: AA=0x92;break; /* '5'and's' */
    case 6: AA=0x82;break; /* '6' */
    case 7: AA=0xf8;break; /* '7' */
    case 8: AA=0x80;break; /* '8' */
    case 9: AA=0x90;break; /* '9' */
    case 10: AA=0x88;break; /* 'A'and'R' */
    case 11: AA=0x83;break; /* 'B' */
    case 12: AA=0xc6;break; /* 'C' */
    case 13: AA=0xa1;break; /* 'D' */
    case 14: AA=0x86;break; /* 'E' */
    case 15: AA=0x8e;break; /* 'F' */
    case 16: AA=0x40;break; /* '0.' */
	case 17: AA=0x79;break; /* '1.' */
	case 18: AA=0x24;break; /* '2.' */
    case 19: AA=0x30;break; /* '3.' */
    case 20: AA=0x19;break; /* '4.' */
    case 21: AA=0x12;break; /* '5.' */
    case 22: AA=0x02;break; /* '6.' */
    case 23: AA=0x78;break; /* '7.' */
    case 24: AA=0x00;break; /* '8.' */
    case 25: AA=0x10;break; /* '9.' */
	case 26: AA=0xc8;break; /* 'n' */
	case 27: AA=0xce;break; /* 'r' */
	case 28: AA=0x87;break; /* 't' */
	case 29: AA=0xc1;break;	/* 'u' */
	case 30: AA=0x8c;break; /* 'p' */
	case '-':AA=0xbf;break; /* 破折号,此处原误为0xdf,系04级王资凯同学指正*/
    case '_':AA=0xf7;break; /* 下划线*/
    case ' ':AA=0xff;break; /* 消隐*/
	
    default: AA=0xff;
  }
  return(AA);
}

/*查找表函数:电压与对应ADC值查找表*/
unsigned int ad_change(unsigned int volt)
{ unsigned int AA;
  switch (volt)
  { 
	case 50: AA=255;break; /* '0' */
    case 51: AA=254;break; /* '1'and'i' */
    case 52: AA=250;break; /* '2' */
    case 53: AA=247;break; /* '3' */
    case 54: AA=243;break; /* '4' */
    case 55: AA=240;break; /* '5'and's' */
    case 56: AA=235;break; /* '6' */
    case 57: AA=231;break; /* '7' */
    case 58: AA=227;break; /* '8' */
    case 59: AA=223;break; /* '9' */
    case 60: AA=219;break; /* '0' */
    case 61: AA=214;break; /* '1'and'i' */
    case 62: AA=210;break; /* '2' */
    case 63: AA=205;break; /* '3' */
    case 64: AA=201;break; /* '4' */
    case 65: AA=197;break; /* '5'and's' */
    case 66: AA=192;break; /* '6' */
    case 67: AA=187;break; /* '7' */
    case 68: AA=183;break; /* '8' */
    case 69: AA=178;break; /* '9' */
	case 70: AA=173;break; /* '0' */
    case 71: AA=168;break; /* '1'and'i' */
    case 72: AA=164;break; /* '2' */
    case 73: AA=159;break; /* '3' */
    case 74: AA=154;break; /* '4' */
    case 75: AA=149;break; /* '5'and's' */
    case 76: AA=144;break; /* '6' */
    case 77: AA=139;break; /* '7' */
    case 78: AA=134;break; /* '8' */
    case 79: AA=128;break; /* '9' */
	case 80: AA=123;break; /* '0' */
    case 81: AA=118;break; /* '1'and'i' */
    case 82: AA=113;break; /* '2' */
    case 83: AA=108;break; /* '3' */
    case 84: AA=102;break; /* '4' */
    case 85: AA=97;break; /* '5'and's' */
    case 86: AA=91;break; /* '6' */
    case 87: AA=86;break; /* '7' */
    case 88: AA=80;break; /* '8' */
    case 89: AA=74;break; /* '9' */
	case 90: AA=69;break; /* '0' */
    case 91: AA=63;break; /* '1'and'i' */
    case 92: AA=58;break; /* '2' */
    case 93: AA=52;break; /* '3' */
    case 94: AA=46;break; /* '4' */
    case 95: AA=40;break; /* '5'and's' */
    case 96: AA=34;break; /* '6' */
    case 97: AA=27;break; /* '7' */
    case 98: AA=22;break; /* '8' */
    case 99: AA=16;break; /* '9' */
	case 100: AA=10;break; /* '0' */
      
    default: AA=0xff;
  }
  return(AA);
}




/**** T0时钟中断服务程序模块
	每5ms被执行一次
*****/

timer0() interrupt 1 using 0         
{
	
	ET0=0;  /*关中断*/

	/* 重新对计数器赋初值,并启动定时计数 */
	TH0=V_TH0;
    TL0=V_TL0;
    TR0=1;

	/* 检测到按键被按下(0)时,相应的指示灯亮(0) */
	if (KEY1==0) led_1 = 0;
	if (KEY2==0) led_2 = 0;
	if (KEY3==0) led_3 = 0;
	if (KEY4==0) led_4 = 0;

	/********************************/
	/*	数码管扫描	                   */
	/********************************/
	output_sel = 0xf0; /*初值,令数码管驱动位无效,指示灯全灭*/

	/* 数码管扫描驱动指针值从1到4重复变换,每5ms间隔对一个数码管进行驱动,20ms一个轮回 */
	if (++digi_scaner>=5) digi_scaner = 1;
	switch (digi_scaner)
	{
		case 1: /* 驱动第一个数码管 */
				output_sel |= 0x01;
				ADDR_8SEG = NUMTOSEG7(digi[0]); /*输出到锁存器U5*/
				break;

		case 2: /* 驱动第二个数码管 */
				output_sel |= 0x02;
				ADDR_8SEG = NUMTOSEG7(digi[1]); /*输出到锁存器U5*/
				break;

		case 3: /* 驱动第三个数码管 */
				output_sel |= 0x04;
				ADDR_8SEG = NUMTOSEG7(digi[2]); /*输出到锁存器U5*/
				break;

		case 4: /* 驱动第四个数码管 */
				output_sel |= 0x08;
				ADDR_8SEG = NUMTOSEG7(digi[3]); /*输出到锁存器U5*/
				break;
	}
	ADDR_SEL = output_sel;     	/*输出到锁存器U6(在电路图中找)*/


	/**********************************************
	以下四段为消抖动程序,以第一个为例说明。
	程序来自2005年4月22日科创讲座的笔记,袁焱老师提供。
	********************************************/

    /* 对按键一进行消抖 */
	cur_sample1 = KEY1;			/* 将按键一的当前状态读取到cur_sample1 */
	if(pre_sample1 != cur_sample1) key1_count++;
	else key1_count = 0;		/* 如果按键的状态发生了改变,则开始计数,反之清零 */
	if(key1_count >= v_keycount)/* 如果按键在改变的状态持续达到v_keycount的次数执行以下片断	*/
	{							
		key1_count = 0;			/* 给出按键被按下的flag,计数器归零,默认状态置为当前状态 */
		if(cur_sample1 == 0) key1_flag = 1;
		pre_sample1 = cur_sample1;
	}

	/* 对按键二进行消抖,原理同按键一,见按键一的注释 */
	cur_sample2 = KEY2;
	if(pre_sample2 != cur_sample2) key2_count++;
	else key2_count = 0;
	if(key2_count >= v_keycount)
	{
		key2_count = 0;
		if(cur_sample2 == 0) key2_flag = 1;
		pre_sample2 = cur_sample2;
	}

	/* 对按键三进行消抖,原理同按键一,见按键一的注释 */
	cur_sample3 = KEY3;
	if(pre_sample3 != cur_sample3) key3_count++;
	else key3_count = 0;
	if(key3_count >= v_keycount)
	{
		key3_count = 0;
		if(cur_sample3 == 0) key3_flag = 1;
		pre_sample3 = cur_sample3;
	}

	/* 对按键四进行消抖,原理同按键一,见按键一的注释 */
	cur_sample4 = KEY4;
	if(pre_sample4 != cur_sample4) key4_count++;
	else key4_count = 0;
	if(key4_count >= v_keycount)
	{
		key4_count = 0;
		if(cur_sample4 == 0) key4_flag = 1;
                                pre_sample4 = cur_sample4;
	}
   /*按键消抖程序结束*/

	/*************************************
	   子模块:ADC部分程序,读取ADC的输出值
	*************************************/
		if(AD_flag==0)
		{	
			if((++DelayCounter)<=30)
			{
				AD_data[AD_ptr] = ADDR_0804 ;  // 读0804
				AD_ptr++;	
			}
		
			AD_flag = 1;
		
		}
	
	ET0=1;  /*开中断*/
}

/*************************************
 PMW信号发生模块,使用定时器1提供的中断
*************************************/
PwmGenerator() interrupt 3 using 1
{
	EA=0;
	TR1=1;
	if(PWM_flag==0)
	{	PWM_OUT=1;
		TH1=hilv_th;
		TL1=hilv_tl;
		PWM_flag=1;
	}
	else
	{
		PWM_OUT=0;
		TH1=lolv_th;
		TL1=lolv_tl;
		PWM_flag=0;
	}
	EA=1;
}

/*开环控制模块,计算v对应的p*/
void Calc_Prop(unsigned int volt)
{
	EA=0;
















  switch (volt)
  { 
	case 50: prop_float=196;break; /* '0' */
    case 51: prop_float=203;break; /* '1'and'i' */

⌨️ 快捷键说明

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