实验报告1.0

更新时间:2024-06-29 05:44:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

实验一 数码管实验

一、实验目的

掌握数码管的使用,了解数码管扫描的原理。

二、实验内容

1、实验原理

开发板设计了一个四位八段共阴极数码管。P0~P7分别连接数码管的阳极,K0~K3分别连接四位的控制端。由于四位数码管公用相同的阳极,要实现数码管每一位显示不同的数字,则必须通过扫描的方式来实现,也就是说某个时刻只有一个数码管处于点亮状态,由于人眼的视觉暂留,看到的效果是是四位数码管都是同时点亮的。

扫描的具体方法是:P口输出第一位数码的段码,K口控制第一位导通其它三位不导通,延时5ms后,P口输出第二位数码管的段码,K口控制第二位导通其它三位不导通,如此直到扫描完第四位后,继续扫描第一位。

2、实验步骤

(1)用跳线帽将JP2的(QH~P7)、(QG~P6)、(QF~P5)、(QD~P3)、(QC~P2)、(QB~P1)、(QA~P0)插针短接,将BDM下载器连接到开发板上,打开开发板电源。

(2)打开光盘文件中的“演示代码\\数码管扫描\\BBIT_LED2.mcp”。 (3)点击(Debug)按钮,将源代码下载到单片机中,进入调试窗口。 (4)点击调试窗口的(Start)按钮,程序开始执行。

(5)观察实验现象,数码管显示“0000”延时一会之后,显示“1111”直到显示“9999”。延时一会儿之后显示“0.0.0.0.”,延时显示“1.1.1.1.”直至“9.9.9.9.”,如此循环。

三、实验原理图

四、实验所用源程序(下划线部分为改动部分)

#include /* common defines and macros */ #include \ /* derivative-specific definitions */ #define CONT1 PORTK_PK3 #define CONT2 PORTK_PK2 #define CONT3 PORTK_PK1 #define CONT4 PORTK_PK0

#define CONT1_dir DDRK_DDRK3 #define CONT2_dir DDRK_DDRK2 #define CONT3_dir DDRK_DDRK1 #define CONT4_dir DDRK_DDRK0 #define DATA PTP

#define DATA_dir DDRP #define LEDCPU PORTK_PK4

#define LEDCPU_dir DDRK_DDRK4 #define BUS_CLOCK 32000000 //总线频率 #define OSC_CLOCK 16000000 //晶振频率

byte shuma[20]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f, //0~9对应的段码

0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef}; //0~9后加小数点对应的段码 unsigned int i;

/*************************************************************/ /* 初始化锁相环 */ /*************************************************************/ void INIT_PLL(void) {

CLKSEL &= 0x7f; //set OSCCLK as sysclk PLLCTL &= 0x8F; //Disable PLL circuit CRGINT &= 0xDF;

#if(BUS_CLOCK == 40000000) SYNR = 0x44;

#elif(BUS_CLOCK == 32000000) SYNR = 0x43;

#elif(BUS_CLOCK == 24000000) SYNR = 0x42; #endif

REFDV = 0x81; //PLLCLK=2×OSCCLK×(SYNDIV+1)/(REFDIV+1)=64MHz ,fbus=32M PLLCTL =PLLCTL|0x70; //Enable PLL circuit

asm NOP; asm NOP;

while(!(CRGFLG&0x08)); //PLLCLK is Locked already CLKSEL |= 0x80; //set PLLCLK as sysclk }

/*************************************************************/ /* 初始化端口 */ /*************************************************************/ void INIT_port(void) {

CONT1_dir = 1; CONT2_dir = 1; CONT3_dir = 1; CONT4_dir = 1; CONT1 = 0; CONT2 = 0; CONT3 = 0; CONT4 = 0; DATA_dir = 0xff; DATA = 0x00; }

/*************************************************************/ /* 延时函数 */ /*************************************************************/ void delay(void) {

unsigned int i,j; for(j=0;j<100;j++) for(i=0;i<60000;i++); }

/*************************************************************/ /* 主函数 */ /*************************************************************/ void main(void) { DisableInterrupts; INIT_PLL(); INIT_port(); LEDCPU_dir=1; LEDCPU=0;

EnableInterrupts;

CONT1=1; //使能数码管的第一位 for(;;) {

for(i=0;i<10;i++) {

DATA = shuma[10-i]; //循环显示数字 delay(); } } }

五、实验流程图

开始 初始化端口 选位端口 计数变量i初始化 i<10? 输出table表中10-i无素 变量增益1 延时

六、总结

1) 了解了实验芯片的基本构造,实验板的电路。 2) 学习了锁相环的倍频功能和实现方式

3) 对于数码管显示的基本硬件原理作掌握并应用,将循环显示,改写为倒计时表

实验二 ATD实验

一、 实验目的

掌握XS128单片机模数转换(ATD)模块的使用。

二、 实验内容

1、在调试窗口的DATA:1窗口中显示了AD_in0和AD_in1两个AD输入通道的值,单击

AD_in0和AD_in1可以显示电压的实时值。

2、用螺丝刀转动滑动变阻器R45和R48,并单击AD_in0和AD_in1,则值会发生变化。

3、用万用表测量电路板上的测试点AD0和AD1的电压值并与AD_in0和AD_in1的值进行对比。数值与电压的对应关系为: ATDDR=(255*U)/5

其中U为测量的电压值,ATDDR为AD转换的数值。

三、 实验原理图

四、 实验所用源程序

#include /* common defines and macros */ #include \ /* derivative-specific definitions */ #define LEDCPU PORTK_PK4

#define LEDCPU_dir DDRK_DDRK4 unsigned char AD_in1,AD_in0;

/*************************************************************/ /* 初始化AD模块 */ /*************************************************************/ void INIT_AD(void) {

ATD0CTL2 = 0x40; //启动A/D模块,快速清零,禁止中断 ATD0CTL1_SRES=0; //选用8位模数转换 ATD0CTL3 = 0x88; //每次只转换一个通道

ATD0CTL4 = 0x01; //AD模块时钟频率为2MHz }

/*************************************************************/ /* 起动AD转换 */ /*************************************************************/ unsigned char AD_capture(unsigned char s) {

unsigned char AD_data; switch(s) {

case 1:

ATD0CTL5 = 0x01; //转换AD01 while(!ATD0STAT2_CCF0); AD_data = ATD0DR0L; break; case 2:

ATD0CTL5 = 0x00; //转换AD00 while(!ATD0STAT2_CCF0); AD_data = ATD0DR0L; break; }

return(AD_data); }

/*************************************************************/ /* 延时函数 */ /*************************************************************/ /*************************************************************/ /* 主函数 */ /*************************************************************/ void main(void) { DisableInterrupts; LEDCPU_dir = 1; INIT_AD();

EnableInterrupts; LEDCPU = 0; for(;;) {

AD_in1 = AD_capture(1); AD_in0 = AD_capture(2); if(AD_in1 > AD_in0) for(;;) {

LEDCPU = 0; delay(); LEDCPU = 1; delay(); } else

LEDCPU = 1; } }

五、 实验流程图

六、 总结

1) 2)

掌握AD转换的基本原理。将输入电压信号同标定信号作二分式比较,如8位就是进行8 次二分比较 对通道进行选择控制,对转换位数可选,对转换量进行比较,并通过led 的亮灯情况输出比较结果,实现人的观察。

实验三 液晶显示实验

一、实验目的

掌握12864液晶模块的使用。

二、实验内容

1、实验原理

XS128开发板上设计了一个带文字库的12864汉显液晶模块。本开发板上的液晶模块有并口和IIC串口操作两种模式。本实验对12864液晶模块进行了并口和模拟IIC串口的操作。 2、实验步骤

2.1并口操作液晶

(1)将液晶模块插到电路板上的J_LCD1接口上。将BDM下载器连接到开发板上,打开开发板电源。

(2)打开光盘文件中的“演示代码\\并口液晶\\IO_LCD.mcp”。

(3)点击Debug按钮,将源代码下载到单片机中,进入调试窗口,将原程序进行一定的修改。

(4)点击调试窗口的Start按钮,程序开始执行。

(5)观察实验现象,液晶屏上显示出《三字经》部分内容,按下按键“KEY1”文字上翻,按下按键“KEY2”文字下翻。 2.2模拟IIC串口操作液晶

(1)将液晶模块插到电路板上的J_LCD1接口上。将BDM下载器连接到开发板上,打开开发板电源。

(2)打开光盘文件中的“演示代码\\并口液晶\\IIC_LCD.mcp”。

(3)点击Debug按钮,将源代码下载到单片机中,进入调试窗口,将原程序进行一定的修改。

(4)点击调试窗口的Start按钮,程序开始执行。

(5)观察实验现象,液晶屏上显示出《三字经》部分内容,按下按键“KEY1”文字上翻,按下按键“KEY2”文字下翻。

三、实验原理图

四、实验所用源程序(下划线部分为改动部分)

}#include /* common defines and macros */ #include \ /* derivative-specific definitions */ #include \ #define LEDCPU PORTK_PK4

#define LEDCPU_dir DDRK_DDRK4 #define KEY1 PTIH_PTIH3 #define KEY2 PTIH_PTIH2

#define KEY1_dir DDRH_DDRH3 #define KEY2_dir DDRH_DDRH2 #define BUS_CLOCK 32000000 //总线频率 #define OSC_CLOCK 16000000 //晶振频率 char *poem[11] = { \人之初\\性本善\\性相近\\习相远\\苟不教\\性乃迁\\教之道\\贵以专\\昔孟母\\择邻处\\} ;

unsigned char single = 0; //液晶翻页的标志符

/*************************************************************/ /* 初始化锁相环 */ /*************************************************************/ /************************************************************/ /* 初始化ECT模块 */ /************************************************************/ /*************************************************************/ /* 初始化按键 */ /*************************************************************/ void init_key(void) {

KEY1_dir =0; //设置为输入 KEY2_dir=0; PPSH = 0x00; //极性选择寄存器,选择下降沿; PIFH = 0x0C; //对PIFH的每一位写1来清除标志位; PIEH = 0x0C; //中断使能寄存器; }

/*************************************************************/ /* 按键中断函数 */ /*************************************************************/ #pragma CODE_SEG __NEAR_SEG NON_BANKED interrupt void PTH_inter(void) {

if(PIFH != 0) //判断中断标志 {

PIFH = 0xff; //清除中断标志 if(KEY2 == 0) {

delay1ms(5); if(KEY2 == 0)

{

if(single <= 0) single = 3; else single-=1 } }

if(KEY1 == 0) {

delay1ms(5); if(KEY1 == 0) {

if(single >= 3) single = 0; else single+=1; } }

lcd_clear();

lcd_string(0,7,poem[single]); lcd_string(0,6,poem[single+1]); lcd_string(0,5,poem[single+2]); lcd_string(0,4,poem[single+3]); lcd_string(0,3,poem[single+4]); lcd_string(0,2,poem[single+5]); lcd_string(0,1,poem[single+6]); lcd_string(0,0,poem[single+7]); } }

#pragma CODE_SEG DEFAULT

/*************************************************************/ /* 主函数 */ /*************************************************************/ void main(void) {

DisableInterrupts; INIT_PLL(); initialize_ect(); init_key(); INIT_PORT(); LEDCPU_dir=1; LEDCPU=0;

EnableInterrupts; delay1ms(100); lcd_clear();

lcd_string(0,7,poem[0]);

lcd_string(0,6,poem[1]); lcd_string(0,5,poem[2]); lcd_string(0,4,poem[3]); lcd_string(0,3,poem[4]); lcd_string(0,2,poem[5]); lcd_string(0,1,poem[6]); lcd_string(0,0,poem[7]); for(;;) { } }

LCD.H改动、实现竖屏自右向左显示

/***************************************************************************/ /* 向LCD发送字符串 */ /***************************************************************************/

void lcd_string(unsigned char row,unsigned char col,char *data1) //row为写入数据所在的行数,col为写入数据所在的列数,*data1为写入的数据 {

for(;row<4&&(*data1)!=0;row++) {

for(;col<8&&(*data1)!=0;col++) {

write_command(adress_table[row*8+col]); delay20us(4); //延时80us

write_Data(*data1++);

delay20us(4); //延时80us write_Data(*data1++);

delay20us(4); //延时80us }

col=0; } }

五、实验流程图

六、总结

1、学习LCD点阵字符原理,LCD集成化,能带字库为编程大大简化,利

于在电脑编程,对字符显示分块在读懂后进行修改设计,对行列循环进行交换,实现三字经的显示,对于按键中断和翻页功能,继承其功能并对于三字经的简化特点,利用计数变量实现对字符翻动的实现避免了大段的枚举。

2、从实验中感悟到查芯片资料,解决问题的思想方法,面对不同问题,

改动程序反复观察结果,反推思考代码。

实验四 电子节气门半实物仿真

一、 实验目的

以节气门为例,学习并掌握利用单片机进行半实物仿真的原理与方法。

二、 实验内容

3、主板的P0/P1接驱动板IN1/IN2 4、上层板的VR M0接主板的AD2 5、节气门的4接主板的AD3 6、节气门的2接主板VCC 7、节气门的6接主板GND

8、节气门的电机线3/5接驱动板OUT1/2

三、 实验原理图

控制框图

四、 实验所用源程序

#include /* common defines and macros */ #include \ /* derivative-specific definitions */ #include #include #include #include \ #define BUS_CLOCK 32000000 //总线频率,改变总线频率直接在此处修改 #define OSC_CLOCK 16000000

//晶振频率

#define LEDCPU PORTK_PK4 #define LEDCPU_dir DDRK_DDRK4 #define DEGREE_MAX 225 #define DEGREE_MIN 16 unsigned char AD_in2,AD_in3;

char AD2Disp[20],AD3Disp[20],Degreestr[20]; //xiebin add #define LED PORTB #define LED_dir DDRB

/*************************************************************/ /* 初始化锁相环 */ /*************************************************************/ /************************************************************/ /* 初始化ECT模块 */ /************************************************************/ /*************************************************************/ /* 延时函数1 */ /*************************************************************/ /*************************************************************/ /* 初始化AD模块 */ /*************************************************************/ /*************************************************************/ /* 起动AD转换 */ /*************************************************************/ /************************************************************/

/* 在液晶上显示AD转换计算量 /************************************************************/ void ADtoDegree(unsigned char ADd, char *dispAD) {

float ttt; //ttt=100 ;

ttt=(100-((ADd-18)*100/207));//yi改正 sprintf(dispAD,\实际开度%%.1f\}

*/ /*************************************************************/ /* 主函数 */ /*************************************************************/ void main(void) { DisableInterrupts; INIT_PLL(); initialize_ect(); INIT_PORT(); INIT_AD(); LEDCPU_dir=1; //xiebin add

LED_dir=0xff; //设置为输出 LED=0xff; //灭8个灯 EnableInterrupts; delay1ms(1000); for(;;) {

AD_in2= AD_capture(2); AD_in3= AD_capture(3); //

sprintf(AD2Disp,\目标AD为%d\ sprintf(AD3Disp,\节气门AD为%d\ ADtoDegree(AD_in3,Degreestr) if(fabs(AD_in3 - AD_in2)>3){ lcd_clear();

lcd_string(0,0,AD2Disp); lcd_string(1,0,AD3Disp); lcd_string(2,0,Degreestr); LEDCPU = 0; } else

LEDCPU = 1; } }

void main(void) {

unsigned char iflag,iDegree; unsigned char temp1,diffNew,diffOld; unsigned char KD,KP;

AD_in3_old=0; iDegree=1; KP=5;

KD=4; diffOld=0;

CLK_Init(); IO_Init();

initialize_ect(); INIT_PORT(); INIT_AD();

//P0--PWM0--IN1 //P1--PWM1--IN2 PWM_01Init(); for(;;) {

AD_in2= AD_capture(2);//目标

AD_in3= AD_capture(3);//节气门,原始230左右 iflag=0;

if((AD_in3 - AD_in2)>2){ //正转, diffNew=AD_in3 - AD_in2;

temp1 = diffNew/KP + (diffNew-diffOld)/KD; if(temp1>20) temp1=20; PWMDTY0=25+temp1; PWMDTY1=0; //mydelay(50); iflag=1; }

else if((AD_in2 - AD_in3)>2){ //反转,关闭节气门 diffNew=AD_in2 - AD_in3;

temp1 = diffNew/KP + (diffNew-diffOld)/KD; if(temp1>20) temp1=20;

PWMDTY0=0;PWMDTY1=33; mydelay(50); PWMDTY0=25+temp1; PWMDTY1=0; //mydelay(50); iflag=2; }

lcd_clear();

sprintf(Row0,\ sprintf(Row1,\正反转为%d\ lcd_string(0,0,Row0); lcd_string(1,0,Row1);

AD_in2_old=AD_in2; AD_in3_old=AD_in3; diffOld=diffNew; } }

五、 实验流程图

开始 初始化锁相环、ECT模块、AD模块 AD转换目标电位2,与实际电位3 增占空比 No 读出实际电位,转化为开度百分比 减占空比 比较目标和实际差值是否大于x Yes 输出字符上屏 延时

六、总结

1) 2)

应用步进电机控制知识,ad转换知识,思考出开度百分数的表示,对比例微分调节的应用,和其系数变化在实验上观察了现象,定性地认识了比例微分的效果,对控制的流程作了感性认知。 预留了一个精度区间,在定义的误差内不调节,能防止系统的抖动,同时这一效果在精度上作出了牺牲。体会工程上通用这个原理。我们在设计中时常就是这种处境,对之的选择权衡,决定于一个产品的应用的主要矛盾。

本文来源:https://www.bwwdw.com/article/kh73.html

Top