一、 实验要求
实验目的:
- 掌握SPI总线的使用方式
- 掌握xpt2046 AD转换芯片的工作原理
- 掌握SPI总线方式实现基于xpt2046的AD转换
- 掌握PWM控制功率的方式
实验内容:
学习xpt2046 AD转换芯片的工作原理,利用SPI总线实现基于该芯片的AD转换,调节滑动变阻器将AD转换的结果显示在数码管上,同时利用PWM控制方式实现LED灯的亮度联动,当AD结果增大时,亮度增加,反之,亮度减小。
二、 实验设计
1.整体思路
初始化: 定义相关的IO口和数据类型。
SPI通信: 实现SPI协议的写和读操作,用于与XPT2046通信。
读取AD数据: 通过SPI通信,发送命令并读取XPT2046返回的AD转换数据。
显示数据: 将读取到的数据显示到数码管上。
2.流程图
图 1 算法设计流程图
- 主要模块设计思路及分析
一、SPI_Write函数:
通过循环将8位数据一位一位地发送到DIN线上。
利用CLK的上升沿将数据放置到DIN上。
二、SPI_Read函数:
通过循环从DOUT线上一位一位地读取12位数据。
利用CLK的下降沿将数据从DOUT读取进来。
三、Read_AD_Data函数:
通过SPI通信发送命令给XPT2046。
等待转换完成,并清除BUSY标志。
读取转换后的AD数据。
四、DigDisplay函数:
用于控制数码管的显示。
通过循环和switch语句选择要点亮的数码管,并发送要显示的数据。
五、readData函数:
这个函数似乎没有完全给出,但从名称来看,它应该是用于读取某种数据(可能是触摸屏的数据)并可能进行进一步的处理。
三、 实现效果
图 2 小于1000显示3个灯
图 3 大于1000显示4个灯
图 4 大于2000显示5个灯
图 5 大于3000显示6个灯
- 总结
代码主要实现了与XPT2046触摸屏控制器的SPI通信,能够发送命令并读取转换后的AD数据,然后将数据显示到数码管上。需要注意的是,代码中的readData函数没有完全给出,可能需要根据实际需求进行完善。
附录:
#ifndef __XPT2046_H_
#define _._XPT2046_H_
//---包含头文件---//
#inclu.de<reg52.h>
#include<intrins.h>
//---.重定义关键词---//
#ifndef uchar
#defin.e uchar unsigned char
#endif
#ifndef uint
#define uint unsigned int
#endif
#ifndef ulong
#define ulong unsigned long
#endif
typedef unsigned int u16; //对数据类型进行声明定义
typedef unsigned char u8;
//---定义使用的IO口---//
sbit DOUT = P3^7; //输出
Sbi.t CLK = P3^6; //时钟
sbit DIN = P3^4; //输入
sbit CS = P3^5; //片选
sbit LSA=P2^2;
Sbit. LSB=P2^3;
sbit LSC=.P2^4;
sbit LS5=P2^5;
sbit L.S6=P2^6;
sbit LS7=P2^7;
u8 DisplayData[8];
u8 code smgduan[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
uint Read_AD_Data(uchar cmd);
uint SPI_Read(void);
void SPI_Write(uchar dat);
#endif
void SP.I_Write(uchar dat)
{
uchar i;
CLK = 0;
for(i=0; i<.8; i++)
{
DIN = dat >> 7; //放置最高位
dat <<= 1;
C.K = 0; //上升沿放置数据
CLK = 1;
}文章来源:https://www.toymoban.com/news/detail-806326.html
}文章来源地址https://www.toymoban.com/news/detail-806326.html
uint SPI_Read(void)
{
uint i, dat=0;
CLK = 0;
for(i=0; i<12; i++) //接收12位数据
{
dat <<= 1;
CLK = 1;
CLK = 0;
dat |= DOUT;
}
Ret.urn dat;
}
uint Read_A.D_Data(uchar cmd)
{
Uch.ar i;
uint AD_Value;
CLK = 0;
CS = 0;
SPI_Write(cmd);
for(i=6; i>0; i--); //延时等待转换结果
CLK = 1; //发送一个时钟周期,清除BUSY
_nop_();
_nop_();
CLK = 0;
_nop_();
_nop_();
AD_Value=SPI_Read();
CS = 1;
return AD_Value;
}
void delay.(u16 i)
{
while(i--);
}
void DigDi.splay()
{
u8 i;
for(i=0;i<4;i++)
{
switch(i) //位选,选择点亮的数码管,
{
case(0):
LSA=0;LSB=0;LSC=0; break;//显示第0位
case(1):
LSA=1;LSB=0;LSC=0; break;//显示第1位
case(2):
LSA=0;LSB=1;LSC=0; break;//显示第2位
case(3):
LSA=1;LSB=1;LSC=0; break;//显示第3位
}
P0=DisplayData[3-i];//发送数据
delay(100); // 延时
P0=0x00;//消隐
}
}
void readData()
{
int cnt,te.mp,lightTime,step;
if(cnt == 25)
{
cnt = 0;
temp = Read_.AD_Data(0x94); // 电位器
DisplayData[0]=smgduan[temp/1000];//千位
DisplayData[1.]=smgduan[temp%1000/100];//百位
DisplayData.[2]=smgduan[temp%1000%100/10];//十位
DisplayData[3]=smgduan[te.mp%1000%100%10];//个位
lightTime = temp / step; // 设置亮灯的时间
}
cnt ++;
if(temp<1000){
LSA=0;
LSB=0;
L.SC=0;
LS5=1;
LS6=1;
LS7=1;
}
else if(temp>=10.00&&temp<2000){
LSA=0;
LSB=0;
LSC=0;
LS5=0;
LS6=1;
LS7=1;
}
else if(temp>=2000&&temp<3000){
LSA=0;
LSB=0;
LS.C=0;
LS5=0;
LS6=0;
LS7=1;
}
else if(temp>=3000){
LSA=0;
LSB=0;
LSC=0;
LS5=0;
LS6=0;
LS7=0;
}
}
void main() {
TMOD = 0x02; // 开启中断方式2
TH0 = 0xa0; // 0.1us
TL0 = .0xa0;
TR0 = 1;
ET0 = 1;
EA = 1;
while(1) {
readData(); // 数据处理
DigDi.splay(); //数码管显示
}
}
到了这里,关于汇编语言与接口技术——AD转换及PWM控制的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!