车辆嵌入式实验报告.docx
《车辆嵌入式实验报告.docx》由会员分享,可在线阅读,更多相关《车辆嵌入式实验报告.docx(22页珍藏版)》请在冰豆网上搜索。
车辆嵌入式实验报告
实验一串口通讯实验
一、实验目的
了解MC9SXS128单片机串行通讯模块、AD模块、PWM模块原理,并掌握使用。
二、实验内容
利用单片机自带的两个串行通讯口SCI0和SCI1,采集电位计电压值,SCI0串口查询发送AD采集值至SCI1,SCI1读取数据,通过PWM模块实现LED灯亮度无极调节。
三、实验原理图
四、实验源程序
#include
#include
#include"derivative.h"
#defineBUS_CLOCK32000000//总线频率
#defineOSC_CLOCK16000000//晶振频率
#defineBAUD9600//波特率
//主控板上LED灯
#defineLEDCPUPORTK_PK4
#defineLEDCPU_dirDDRK_DDRK4
#defineLED_ON0
#defineLED_OFF1
unsignedcharAD;
unsignedchardata_receive;
unsignedinta=0;//串口接收指示灯
//函数初始化
voidINIT_AD(void);
unsignedcharAD_capture(void);
voidINIT_PLL(void);//初始化锁相环
voidinit_pwm(void);//初始化PWM
voidINIT_SCI(void);//初始化串口
voidSCI0_send(unsignedchardata);//串口发送程序
unsignedcharSCI1_receive(void);//串口接收函数
//串口中断接收函数
#pragmaCODE_SEG__NEAR_SEGNON_BANKED//中断函数置于非分页区内
voidinterrupt21receivedata(void)
{
a++;
data_receive=SCI1_receive();
PWMDTY0=data_receive;
if(a==1000)
{
a=0;
LEDCPU=~LEDCPU;
}
}
#pragmaCODE_SEGDEFAULT//后续代码置于默认区域内
voidmain(void)
{
LEDCPU_dir=1;//定义为输出
LEDCPU=LED_ON;
DisableInterrupts;
INIT_PLL();
INIT_AD();
init_pwm();
INIT_SCI();
EnableInterrupts;
while
(1)
{
AD=AD_capture();
SCI0_send(AD);
}
}
unsignedcharSCI1_receive(void)
{
if(!
SCI1SR1_RDRF);//等待发送数据寄存器满//接收数据寄存器空标志位
return(SCI1DRL);
}
voidINIT_SCI(void)
{
SCI0BD=BUS_CLOCK/16/BAUD;//设置SCI0波特率为9600
SCI0CR1=0x00;//设置SCI0为正常模式,八位数据位,无奇偶校验//10位数据异步传输,1位起始位,一位停止位,8位数据位
SCI0CR2=0x2c;//允许接收和发送数据,允许接收中断功能
SCI1BD=BUS_CLOCK/16/BAUD;//设置SCI1波特率为9600
SCI1CR1=0x00;//设置SCI1为正常模式,八位数据位,无奇偶校验//10位数据异步传输,1位起始位,一位停止位,8位数据位
SCI1CR2=0x2c;//允许接收和发送数据,允许接收中断功能
}
voidINIT_PLL(void)
{
CLKSEL&=0x7f;//setOSCCLKassysclk
PLLCTL&=0x8F;//DisablePLLcircuit
CRGINT&=0xDF;
SYNR=0x43;
REFDV=0x81;//PLLCLK=2×OSCCLK×(SYNR+1)/(REFDV+1)=64MHz,fbus=32M
PLLCTL=PLLCTL|0x70;//EnablePLLcircuit
asmNOP;
asmNOP;
while(!
(CRGFLG&0x08));//PLLCLKisLockedalready
CLKSEL|=0x80;//setPLLCLKassysclk
}
voidINIT_AD(void)
{
ATD0CTL2=0x40;//启动A/D模块,快速清零,禁止中断
ATD0CTL1_SRES=0;//选用8位模数转换
ATD0CTL3=0x88;//每次只转换一个通道
ATD0CTL4=0x07;//AD模块时钟频率为2MHz
}
unsignedcharAD_capture(void)
{
unsignedcharAD_data;
ATD0CTL5=0x08;//转换AD08
while(!
ATD0STAT0_SCF);
AD_data=ATD0DR0L;
return(AD_data);
}
voidinit_pwm(void)
{
PWMPOL_PPOL0=1;//通道的极性为高电平有效
PWMPRCLK=0x22;//A时钟和B时钟的分频系数为4,频率为8MHz
PWMSCLA=0x04;//SA时钟频率为1MHz
PWMSCLB=0x04;//SB时钟频率为1MHz
PWMCLK=0xFf;//0,1,2,3用SA时钟;4,5,6,7用SB时钟
PWMCAE=0x00;//脉冲模式为左对齐模式
PWMPER0=255;//通道0的周期为3.9KHz
PWMDTY0=0;//通道0的占空比设置
PWME_PWME0=1;//使能PWM信号
}
voidSCI0_send(unsignedchardata)
{
while(!
SCI0SR1_TDRE);//等待发送数据寄存器(缓冲器)为空//发送数据寄存器空标志位
SCI0DRL=data;
}
五、实验流程图
六、实验总结
串口SCI0查询发送方式为死循环方式,未调节发送间隔时间,如果采用硬件PIT定时中断发送或软件延时发送,则可调节发送间隔时间,效果更佳。
实验二液晶画点显示电压波形实验
一、实验目的
了解并掌握12864液晶屏、OLED屏显示原理,及MC9SXS128PIT模块、AD模块使用及中断编写方式。
二、实验内容
通过AD模块采集电位计电压值,实现12864液晶及OLED屏显示电压波形曲线。
三、实验原理图
四、实验源程序
1、12864液晶屏关键程序
unsignedchargdram[32][32];
unsignedchardianzhen[128];
//请空GDRAM
voidclear_gdram(void)
{
unsignedcharx,y;
for(y=0;y<32;y++)
{
for(x=0;x<32;x++)
{
gdram[x][y]=0x00;
}
}
}
//设置为绘图模式
voidgraph(void)
{
write_command(0x36);
delay20us(4);
}
//画点,刷新gdram[]
voiddraw_point(unsignedcharx,unsignedchary)
{
unsignedintvx,vy,by,temp;
if(x>127||y>63)
return;
vy=x/8;
by=x%8;
if(y<=31)
{
vx=31-y;
vy=vy+16;
}
else
{
vx=63-y;
}
temp=1<<(7-by);
gdram[vx][vy]|=temp;
}
//更新GDRAM内容
voidlcd_refresh(void)
{
unsignedcharx,y;
for(y=0;y<32;y++)
{
for(x=0;x<16;x++)
{
write_command(0x34);//关闭绘图模式
write_command(y+0x80);//行地址
write_command(x+0x80);//列地址
write_command(0x30);
write_Data(gdram[y][2*x]);
write_Data(gdram[y][2*x+1]);
}
}
}
//中断程序
#pragmaCODE_SEG__NEAR_SEGNON_BANKED
voidinterrupt66pit0(void)
{
if(PITTF_PTF0==1)
PITTF_PTF0=1;//清除标志位
ad=AD_capture();
y=ad/4;
if(x<128)
{
draw_point(x,y);
dianzhen[x]=y;
x++;
}
else
{
clear_gdram();
for(i=0;i<127;i++)
{
dianzhen[i]=dianzhen[i+1];
draw_point(i,dianzhen[i]);
}
dianzhen[127]=y;
draw_point(127,y);
}
lcd_refresh();
graph();
LEDCPU=~LEDCPU;
}
#pragmaCODE_SEGDEFAULT
2、OLED屏关键程序
unsignedchargram[128][8];
//更新GRAM内容
voidRefresh_Gram(void)
{
unsignedchari,n;
for(i=0;i<8;i++)
{
OLED_WrCmd(0xb0+i);
OLED_WrCmd(0x00);
OLED_WrCmd(0x10);
for(n=0;n<128;n++)
{
OLED_WrDat(gram[n][i]);
}
}
}
//画点,刷新gram[]
voidDraw_Point(unsignedcharx,unsignedchary)
{
unsignedcharpos,bx,temp=0;
if(x>127||y>63)
return;
pos=7-y/8;
bx=y%8;
temp=1<<(7-bx);
gram[x][pos]|=temp;
}
//清空GRAM
voidClear(void)
{
unsignedchari,n;
for(i=0;i<8;i++)
for(n=0;n<128;n++)
gram[n][i]=0X00;
Refresh_Gram();
}
//中断程序
#pragmaCODE_SEG__NEAR_SEGNON_BANKED
voidinterrupt66pit0(void)
{
if(PITTF_PTF0==1)
PITTF_PTF0=1;//清除标志位
ad=AD_capture();
y=ad/4;
if(x<128)
{
Draw_Point(x,y);
x++;
}
else
{
for(j=0;j<8;j++)
{
for(i=0;i<127;i++)
{
gram[i][j]=gram[i+1][j];
}
for(i=0;i<8;i++)
gram[127][i]=0x00;
Draw_Point(127,y);
}
}
Refresh_Gram();
}
#pragmaCODE_SEGDEFAULT
五、实验流程图
1、12864液晶屏程序流程图
2、OLED屏程序流程图
六、实验效果
1、12864液晶屏实验效果
2、OLED屏实验效果
七、实验总结
12864液晶屏在画图模式中,更改GDRAM数据时,需要关闭画图模式而关闭12864液晶屏显示,在完成数据更改后再次显示,因屏幕自身性能限制,关闭显示和再次开启过程的时间较长,所以ad采样率较低,曲线的连续性较差;而OLED屏则克服了这一缺陷,采样率在较高情况下也可完整显示,曲线的连续性较好。
实验三闭环控制节气门开度实验
一、实验目的
了解并掌握增量式PID算法,MC9SXS128AD模块、PWM模块、PIT模块原理及使用。
二、实验内容
采集转把AD值和节气门AD值,通过增量式PID算法,输出PWM方波驱动节气门直流电机,调节节气门转动角度,使其随转把转动角度变化而变化。
三、实验原理图
四、实验源程序
#include/*commondefinesandmacros*/
#include"derivative.h"/*derivative-specificdefinitions*/
#include"OLED.h"
#defineBUS_CLOCK32000000//总线频率
#defineOSC_CLOCK16000000//晶振频率
unsignedcharad,ad04;
intchazhi_old,chazhi=0;
intsum,inc=0;
floatkp=0.025;
floatki=0.00002;
intout=0;
voidINIT_AD(void)
{
ATD0CTL2=0x40;//启动A/D模块,快速清零,禁止中断
ATD0CTL1_SRES=0;//选用8位模数转换
ATD0CTL3=0x88;//每次只转换一个通道
ATD0CTL4=0x07;//AD模块时钟频率为2MHz
}
unsignedcharAD_capture(void)
{
unsignedcharAD_data;
ATD0CTL5=0x03;//转换AD03
while(!
ATD0STAT0_SCF);
AD_data=ATD0DR0L;
return(AD_data);
}
unsignedcharAD_capture_04(void)//摇杆
{
unsignedcharAD_data;
ATD0CTL5=0x04;//转换AD04
while(!
ATD0STAT0_SCF);
AD_data=ATD0DR0L;
return(AD_data);
}
voidinit_PIT(void)
{
PITMTLD0=255;//为0通道8位计数器赋值
PITLD0=400;//为0通道16位计数器赋值//(31+1)*(99+1)=16000000个总线周期=100us
PITMUX_PMUX0=0;//第0通道使用微计数器0
PITCE_PCE0=1;//第0通道计数器工作
PITCFLMT=0X80;//使能周期中断定时器
PITINTE_PINTE0=1;//0通道定时器定时中断被使能
}
voidINIT_PLL(void)
{
CLKSEL&=0x7f;//setOSCCLKassysclk
PLLCTL&=0x8F;//DisablePLLcircuit
CRGINT&=0xDF;
SYNR=0x43;
REFDV=0x81;//PLLCLK=2×OSCCLK×(SYNDIV+1)/(REFDIV+1)=64MHz,fbus=32M
PLLCTL=PLLCTL|0x70;//EnablePLLcircuit
asmNOP;
asmNOP;
while(!
(CRGFLG&0x08));//PLLCLKisLockedalready
CLKSEL|=0x80;//setPLLCLKassysclk
}
voidinit_pwm(void)
{
PWMPOL_PPOL0=1;//通道的极性为高电平有效
PWMPOL_PPOL1=1;//通道的极性为高电平有效
PWMPRCLK=0x22;//A时钟和B时钟的分频系数为4,频率为8MHz
PWMSCLA=0x04;//SA时钟频率为1MHz
PWMSCLA=0x04;//SB时钟频率为1MHz
PWMCLK=0x03;//0和1用SA时钟
PWMCAE=0x00;//脉冲模式为左对齐模式
PWMPER0=255;//通道0的周期为10KHz
PWMPER1=255;//通道1的周期为10KHz
PWMDTY0=0;//通道0的占空比设置
PWMDTY1=0;//通道1的占空比设置
PWME_PWME0=1;
PWME_PWME1=1;
}
#pragmaCODE_SEG__NEAR_SEGNON_BANKED
voidinterrupt66pit0(void)
{
if(PITTF_PTF0==1)
PITTF_PTF0=1;//清除标志位
ad04=AD_capture_04();
ad=AD_capture();
chazhi_old=chazhi;
chazhi=ad04-(255-ad);
sum=sum+chazhi;
out=out+(int)(kp*chazhi+ki*sum);
if(out>255)
out=255;
elseif(out<0)
out=0;
PWMDTY01=out;
}
#pragmaCODE_SEGDEFAULT
voidmain(void)
{
DisableInterrupts;
init_pwm();
INIT_PLL();
INIT_AD();
init_PIT();
OLED_Init();
EnableInterrupts;
for(;;)
{
}
}
五、实验流程图
六、实验总结
本次实验没有采用老师所给程序,而是采用增量式PI控制,通过不断设置比例和积分参数以到达理想实验结果,虽然最终节气门转动角度稳定在理想位置,但是其在稳定前的超调量与稳定时间均比较大,系统的快速响应性不是很理想。
课程总结