当前位置:网站首页>51单片机学习记录(六)IIC,ADC部分
51单片机学习记录(六)IIC,ADC部分
2022-06-10 01:25:00 【桃成蹊2.0】
51单片机差不多就这样了,相关的代码可以看我的gitee,可以减少自己造轮子的痛苦:51单片机学习记录
1、iic部分
前面讲过的关于IIC的原理,可以帮助理解,有对iic不太清楚的可以看下:
stm32配置总结-iic的使用
面试中比较常问的通信协议总结
这里开发板也是接了一个AT24C02来用作IIC实验,这个芯片来做iic学习还是很经典的啊
这个之前写过stm32相关的文章:stm32配置总结-iic的使用,有需要的可以去查看下。
这里51单片机没有硬件iic,需要我们自己去写软件iic,这里直接参考普中科技的例程:
#include "iic.h"
void iic_start(void)
{
IIC_SDA = 1;
delay_10us(1);
IIC_SCL = 1;
delay_10us(1);
IIC_SDA = 0; //当SCL为高电平时,SDA由高变为低
delay_10us(1);
IIC_SCL = 0; //钳住I2C总线,准备发送或接收数据
delay_10us(1);
}
void iic_stop(void)
{
IIC_SDA = 0;
delay_10us(1);
IIC_SCL = 1;
delay_10us(1);
IIC_SDA = 1; //当SCL为高电平时,SDA由低变为高
delay_10us(1);
}
void iic_ack(void)
{
IIC_SCL = 0;
IIC_SDA = 0; // SDA为低电平
delay_10us(1);
IIC_SCL = 1;
delay_10us(1);
IIC_SCL = 0;
}
void iic_nack(void)
{
IIC_SCL = 0;
IIC_SDA = 1; // SDA为高电平
delay_10us(1);
IIC_SCL = 1;
delay_10us(1);
IIC_SCL = 0;
}
u8 iic_wait_ack(void)
{
u8 time_temp = 0;
IIC_SCL = 1;
delay_10us(1);
while (IIC_SDA) //等待SDA为低电平
{
time_temp++;
if (time_temp > 100) //超时则强制结束IIC通信
{
iic_stop();
return 1;
}
}
IIC_SCL = 0;
return 0;
}
void iic_write_byte(u8 dat)
{
u8 i = 0;
IIC_SCL = 0;
for (i = 0; i < 8; i++) //循环8次将一个字节传出,先传高再传低位
{
if ((dat & 0x80) > 0)
IIC_SDA = 1;
else
IIC_SDA = 0;
dat <<= 1;
delay_10us(1);
IIC_SCL = 1;
delay_10us(1);
IIC_SCL = 0;
delay_10us(1);
}
}
u8 iic_read_byte(u8 ack)
{
u8 i = 0, receive = 0;
for (i = 0; i < 8; i++) //循环8次将一个字节读出,先读高再传低位
{
IIC_SCL = 0;
delay_10us(1);
IIC_SCL = 1;
receive <<= 1;
if (IIC_SDA)
receive++;
delay_10us(1);
}
if (!ack)
iic_nack();
else
iic_ack();
return receive;
}
读写at24c02部分也是:
#include "at24c02.h"
void at24c02_write_one_byte(u8 addr,u8 dat)
{
iic_start();
iic_write_byte(0XA0); //发送写命令
iic_wait_ack();
iic_write_byte(addr); //发送写地址
iic_wait_ack();
iic_write_byte(dat); //发送字节
iic_wait_ack();
iic_stop(); //产生一个停止条件
delay_ms(10);
}
u8 at24c02_read_one_byte(u8 addr)
{
u8 temp=0;
iic_start();
iic_write_byte(0XA0); //发送写命令
iic_wait_ack();
iic_write_byte(addr); //发送写地址
iic_wait_ack();
iic_start();
iic_write_byte(0XA1); //进入接收模式
iic_wait_ack();
temp=iic_read_byte(0); //读取字节
iic_stop(); //产生一个停止条件
return temp; //返回读取的数据
}
这样就可以在主函数中进行读写了。
2、ADC部分
这里51单片机好像也没有ADC的片上外设,所以需要其他的AD模块来实现对应的功能,这里用的是XPT2046这个芯片来实现的,下面来看下这个芯片是如何实现对应的功能的:
可以看到这个芯片原来是作为触摸屏芯片的,是一个12位的AD,监测范围0到6V。下面是相关的引脚介绍:
工作模式说明如下:
单端模式和差分模式的选择方式:(ADC就直接单端模式即可)
使用IIC等方式可以进行通信,时序图如下所示:
说明如下:
其中控制字的命令说明如下:
最终的代码如下:
#include "adc.h"
#include "intrins.h"
void xpt2046_wirte_data(u8 dat)
{
u8 i;
CLK = 0;
_nop_();
for (i = 0; i < 8; i++) //循环8次,每次传输一位,共一个字节
{
DIN = dat >> 7; //先传高位再传低位
dat <<= 1; //将低位移到高位
CLK = 0; // CLK由低到高产生一个上升沿,从而写入数据
_nop_();
CLK = 1;
_nop_();
}
}
u16 xpt2046_read_data(void)
{
u8 i;
u16 dat = 0;
CLK = 0;
_nop_();
for (i = 0; i < 12; i++) //循环12次,每次读取一位,大于一个字节数,所以返回值类型是u16
{
dat <<= 1;
CLK = 1;
_nop_();
CLK = 0; // CLK由高到低产生一个下降沿,从而读取数据
_nop_();
dat |= DOUT; //先读取高位,再读取低位。
}
return dat;
}
u16 xpt2046_read_adc_value(u8 cmd)
{
u8 i;
u16 adc_value = 0;
CLK = 0; //先拉低时钟
CS = 0; //使能XPT2046
xpt2046_wirte_data(cmd); //发送命令字
for (i = 6; i > 0; i--)
; //延时等待转换结果
CLK = 1;
_nop_();
CLK = 0; //发送一个时钟,清除BUSY
_nop_();
adc_value = xpt2046_read_data();
CS = 1; //关闭XPT2046
return adc_value;
}
3、DAC部分
这里DAC是通过PWM结合电路来实现的,前面已经介绍过ADC相关的内容,这里不再赘述了,ADC的工作原理如下所示
使用的电路如下所示,这里我们要实现ADC的功能,只要输出的对应的PWM即可。
边栏推荐
- Custom action logging annotation
- Curriculum Learning and Graph Neural Networks (or Graph Structure Learning)
- Why do programmers run away after two years?
- Where is safe and reliable for Hangzhou futures to open an account?
- 物联网工程设计与实施
- 国内现货白银有哪些好技术:常见指标的简单用法
- 【ICLR 2022】Towards Continual Knowledge Learning of Language Models
- 免费批量导入生成sitemap地图的软件
- 地图瓦片数据的多种利用形式以及瓦片数据的浏览显示
- What is the difference between encryptors and database encryption products?
猜你喜欢

为什么芯片设计也需要「匠人精神」?

Various utilization forms of map tile data and browsing display of tile data

1265_ Implementation analysis of adding tasks to task ready linked list in FreeRTOS

Thingsboard tutorial (19): overview of rule nodes

比你想象中更强大的 reduce 以及对敲码的思考

Curriculum Learning and Graph Neural Networks (or Graph Structure Learning)
![[Multisim Simulation] differential proportional amplifier circuit](/img/29/951bee086128c1a0a4ec33ddc82bee.png)
[Multisim Simulation] differential proportional amplifier circuit

地图瓦片数据的多种利用形式以及瓦片数据的浏览显示

A junior college programmer in hupiao, he worked out with liuzhenhong while taking 22K offers

The project was successful, and the project manager was the greatest contributor?
随机推荐
iNFTnews | NFT在Web3经济里的未来
为什么芯片设计也需要「匠人精神」?
A junior college programmer in hupiao, he worked out with liuzhenhong while taking 22K offers
【LeetCode】287. Find duplicates
有机金属多孔材料MOF(Fe)包载喜树碱,藤黄酸、吲哚菁绿|RMOF-3包载紫杉醇定制
Picture batch download + picture mosaic: multiple pictures constitute the Dragon Boat Festival Ankang!
【Multisim仿真】差分比例放大电路
Disorder of flinksql
Linux安装MySQL脚本
[從零開始學習FPGA編程-16]:快速入門篇 - 操作步驟2-4- Verilog HDL語言描述語言基本語法(軟件程序員和硬件工程師都能看懂)
window.open(url)多次打开下载链接被浏览器拦截问题解决方案,js实现循环访问多个下载链接
Luogu p1220 turn off street light problem solving section DP
【LeetCode】128. 最长连续序列
【LeetCode】64. 最小路径和
【LeetCode】437. Path sum III
Solution to the problem of the greatest common divisor and the least common multiple of Luogu p1029
TCP 连接中的keep-alive
iNFTnews | NFT在Web3經濟裏的未來
Sword finger offer 10- ii Frog jumping on steps
软件工程期末复习