noonezero
发表于 2023-10-5 15:25:59
本帖最后由 noonezero 于 2023-10-5 18:17 编辑
第十九课:NTC温度采集
1.NTC原理
NTC是指随温度上升电阻呈指数关系减小,具有负温度系数的热敏电阻现象和材料
公式
代码:记得端口配置高阻输入
我按课件送的表做的,常温显示41度多,估计是表的问题
#include "config.h"
#include <STC32G.H>
#include "../COMM/stc32_stc8_usb.h"
#include "stdio.h"
#include "ntc.h"
void sys_init();
//USB调试及复位所需定义
char *USER_DEVICEDESC = NULL;
char *USER_PRODUCTDESC = NULL;
char *USER_STCISPCMD = "@STCISP#";
// ADC初始化
void ADC_init()
{
ADCTIM = 0x3F; // 设置ADC内部时序
ADCCFG = 0x2F; // 数据右对齐,方便合二为一。时钟选择为最慢
ADC_CONTR = 0x83; // 1000 0011 选择通道0011 P1.3
}
// ADC读取
int ADC_Read()
{
int res; // ADC数值保存变量
ADC_START = 1; // 开启ADC转化
_nop_(); // 空操作指令
_nop_();
while(!ADC_FLAG); // 等待ADC转换结束
ADC_FLAG = 0; // 手动清零
res = (ADC_RES << 8) | ADC_RESL; // 计算ADC数值
return res;
}
void main()
{
int adcval;
int res;
P0M1 |= 0x08;
sys_init();
usb_init();//USB初始化
EA = 1;
ADC_init();
adcval = ADC_Read();
res = Temp_Cal(adcval);
while(1)
{
if (bUsbOutReady)
{
//USB_SendData(UsbOutBuffer, 64);
usb_OUT_done();
printf("temp \t%d\tadc \t%d\r\n", res, adcval);
}
}
}
void sys_init()
{
WTST = 0;//设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
EAXFR = 1; //扩展寄存器(XFR)访问使能
CKCON = 0; //提高访问XRAM速度
P0M1 = 0x30; P0M0 = 0x30; //设置P0.4、P0.5为漏极开路(实验箱加了上拉电阻到3.3V)
P1M1 = 0x32; P1M0 = 0x32; //设置P1.1、P1.4、P1.5为漏极开路(实验箱加了上拉电阻到3.3V), P1.1在PWM当DAC电路通过电阻串联到P2.3
P2M1 = 0x3c; P2M0 = 0x3c; //设置P2.2~P2.5为漏极开路(实验箱加了上拉电阻到3.3V),设置开漏模式需要断开PWM当DAC电路中的R2电阻
P3M1 = 0x50; P3M0 = 0x50; //设置P3.4、P3.6为漏极开路(实验箱加了上拉电阻到3.3V)
P4M1 = 0x3c; P4M0 = 0x3c; //设置P4.2~P4.5为漏极开路(实验箱加了上拉电阻到3.3V)
P5M1 = 0x0c; P5M0 = 0x0c; //设置P5.2、P5.3为漏极开路(实验箱加了上拉电阻到3.3V)
P6M1 = 0xff; P6M0 = 0xff; //设置为漏极开路(实验箱加了上拉电阻到3.3V)
P7M1 = 0x00; P7M0 = 0x00; //设置为准双向口
}
noonezero
发表于 2023-10-6 15:05:25
本帖最后由 noonezero 于 2023-10-6 16:54 编辑
第二十课:串口通信
1.什么是通信
通信是指设备之间通过一定协议进行的信息交换。
2.什么是串口通信
串口通信是指外设和计算机之间,通过数据信号线,地线,控制线等,按位进行传输数据的一种通讯方式。
优点是,使用的数据线少,节约通信成本。
缺点是,传输速度比并行低
3,全双工和半双工的区别
4.串口通信基础知识
5.解决传输距离问题
代码:
我尝试加入自动下载没成功,暂时先不用自动下载
我没冲哥232转USB线,直接用的串口工具,串口排针引脚如下,我用的P46 P47
#include <STC32G.H>
void sys_init();
#define FOSC 11059200UL // 定义无符号长整数型 避免计算溢出
#define BRT (65536 - (FOSC/115200+2)/4) // 加2操作是为了让keil编译器自动实现四舍五入运算
bit busy; // 忙碌标志位 1,忙碌0,空闲
char wptr; // 接收到的数据个数
char rptr;
char buffer;
void Usaart2_Init(void)
{
P_SW2 = 0x80;
P_SW2 |= 0x01; // 将串口2的引脚切换到P46 P47
S2CFG = 0x01; // 用串口2此位必须置1,否则有不可预测错误
S2CON = 0x50; // 0101串口控制寄存器 配置模式 允许串口接收数据
T2L = BRT;
T2H = BRT >> 8;
T2x12 = 1;
T2R = 1;
wptr = 0x00;
rptr = 0x00;
busy = 0;
}
void Uart2Isr() interrupt 8
{
if(S2TI)
{
S2TI = 0;
busy = 0;
}
if(S2RI)
{
S2RI = 0;
buffer = S2BUF;
wptr &= 0x0F;
}
}
void Uart2Send(char dat)
{
while(busy);
busy = 1;
S2BUF = dat;
}
void Uart2SendStr(char *p)
{
while(*p)
{
Uart2Send(*p++);
}
}
void main()
{
sys_init();
EA = 1;
Usaart2_Init();
IE2 = 0x01;
Uart2SendStr("noonezero\r\n");
while(1)
{
if(rptr != wptr)
{
Uart2Send(buffer);
rptr &= 0x0F;
}
}
}
void sys_init()
{
WTST = 0;//设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
EAXFR = 1; //扩展寄存器(XFR)访问使能
CKCON = 0; //提高访问XRAM速度
P0M1 = 0x30; P0M0 = 0x30; //设置P0.4、P0.5为漏极开路(实验箱加了上拉电阻到3.3V)
P1M1 = 0x32; P1M0 = 0x32; //设置P1.1、P1.4、P1.5为漏极开路(实验箱加了上拉电阻到3.3V), P1.1在PWM当DAC电路通过电阻串联到P2.3
P2M1 = 0x3c; P2M0 = 0x3c; //设置P2.2~P2.5为漏极开路(实验箱加了上拉电阻到3.3V),设置开漏模式需要断开PWM当DAC电路中的R2电阻
P3M1 = 0x50; P3M0 = 0x50; //设置P3.4、P3.6为漏极开路(实验箱加了上拉电阻到3.3V)
P4M1 = 0x3c; P4M0 = 0x3c; //设置P4.2~P4.5为漏极开路(实验箱加了上拉电阻到3.3V)
P5M1 = 0x0c; P5M0 = 0x0c; //设置P5.2、P5.3为漏极开路(实验箱加了上拉电阻到3.3V)
P6M1 = 0xff; P6M0 = 0xff; //设置为漏极开路(实验箱加了上拉电阻到3.3V)
P7M1 = 0x00; P7M0 = 0x00; //设置为准双向口
}
noonezero
发表于 2023-10-12 11:48:15
第二十一课:串口应用
这节课主要讲了如何运用串口实现控制点灯,显示数码管等操作,主要是判断是否有结束符\r\n来进行操作
这节课感觉还是没有如何应用好,代码以后再补
noonezero
发表于 2023-10-12 16:35:26
第二十二课:CDC串口通信
1.CDC串口通信的好处
1.数据传输更快:USB-CDC虚拟串口忽略传统串口的波特率,传输速度的比特率为全速USB通信速度12MBPS(每秒12M位)
2.使用更简单便携:USB-CDC虚拟串口忽略传统串口的起始位、停止位等冗余信息
3.数据传输更可靠:USB-CDC虚拟串口丢弃传统串口简单的软件奇偶校验机制,USB-CDC虚拟串口数据传输时有USB硬件CRC校验,以及校验出错重传机制,保证数据100%正确
4.自动缓存数据:USB-CDC虚拟串口会自动缓存数据。单片机在没有处理完成上位机下传上一笔数据时,如果此时上位机又有新的数据下传,虚拟串口会自动将新的数据缓存数据。从而保证数据100%不会丢失或覆盖。
2.CDC自动下载
noonezero
发表于 2023-10-12 19:13:31
本帖最后由 noonezero 于 2023-10-12 19:49 编辑
第二十三课:看门狗
1.看门狗时什么
看门狗时一个计数器,它的基本功能时在软件问题和程序跑偏后重启系统。看门狗正常工作时会自动计数,程序进程会定时将其归零。如果系统在某些地方卡住或者跑了,定时器就会溢出,使系统强制复位
2.看门狗的意义
软件的可靠性一直是一个关键问题。任何使用软件的人都可能遇到电脑死机或者程序失控的问题,这种问题在嵌入式系统中也存在
由于单片机抗干扰能力有限,在工业现场仪器仪表中,经常因电压不稳和电弧干扰而死机。
在无人值守的情况下,系统因干扰无法重启。为了保证系统受到干扰后能自动恢复正常,就需要看门狗
3.实现原理
系统运行以后也就启动了看门狗计数器,看门狗就开始自动计数。如果到了一定的时间还不去清理看门狗(喂狗),那么看门狗计数器就会溢出从而引起看门狗中断,造成系统复位。
4.代码
noonezero
发表于 2023-10-13 10:53:41
本帖最后由 noonezero 于 2023-10-14 08:12 编辑
第二十四课:比较器
1.内部结构图
CMPPS:比较器正端输入选择
CMPNS:比较器负端输入选择
DISFLT:模拟滤波功能控制
LCDTY:数字滤波功能控制
CMPRES:比较器的比较结果。只读
CMPOE:比较器结果输出控制位
CMPO_S:比较器输出脚选择位
CMPIF:比较器中断标志位。当 PIE 或 NIE 被使能后,产生中断信号,硬件自动将 CMPIF 置 1,并向 CPU 提出中断请求。需要软件清零。
代码:
#include <STC32G.H>
#include "../COMM/stc32_stc8_usb.h"
void sys_init();
//USB调试及复位所需定义
char *USER_DEVICEDESC = NULL;
char *USER_PRODUCTDESC = NULL;
char *USER_STCISPCMD = "@STCISP#";
void CMP_Init()
{
//CMPEXCFG |= 0x40; //比较器DC迟滞输入选择,0:0mV; 0x40:10mV; 0x80:20mV; 0xc0:30mV
//CMPEXCFG &= ~0x04; //P3.6为CMP-输入脚
CMPEXCFG |= 0x04; //内部1.19V参考电压为CMP-输入脚
CMPEXCFG &= ~0x03; //P3.7为CMP+输入脚
//CMPEXCFG |= 0x01; //P5.0为CMP+输入脚
//CMPEXCFG |= 0x02; //P5.1为CMP+输入脚
//CMPEXCFG |= 0x03; //ADC输入脚为CMP+输入脚
CMPCR2 = 0x00;
INVCMPO = 0; //比较器正向输出
//INVCMPO = 1; //比较器反向输出
DISFLT = 0; //使能0.1us滤波
//DISFLT = 1; //禁止0.1us滤波
//CMPCR2 &= ~0x3f; //比较器结果直接输出
CMPCR2 |= 0x10; //比较器结果经过16个去抖时钟后输出
CMPCR1 = 0x00;
//PIE = 0; //禁止比较器上升沿中断
PIE = 1; //使能比较器上升沿中断
//NIE = 0; //禁止比较器下降沿中断
NIE = 1; //使能比较器下降沿中断
//CMPOE = 0; //禁止比较器输出
CMPOE = 1; //使能比较器输出
CMPO_S = 0; //选择P3.4作为比较器输出脚
//CMPO_S = 1; //选择P4.1作为比较器输出脚
CMPEN = 1; //使能比较器模块
}
void main()
{
sys_init();
IRC48MCR = 0x80; // 使能内部48M的USB专用IRC
while(!(IRC48MCR & 0x01));
USBCLK = 0x00; // 设置USB时钟源为内部48M的USB专用IRC
USBCON = 0x90; // 使能USB功能
usb_init(); // 调用USB CDC初始化库函数
EA = 1;
EUSB = 1; // 使能USB中断
while(DeviceState != DEVSTATE_CONFIGURED); // 等待USB配置完成
CMP_Init();
P6 = 0x00;
while(1)
{
if (bUsbOutReady) // 当硬件接收完成上位机通过串口助手发送数据后会自动将
{ // bUsbOutReady 置1
USB_SendData(UsbOutBuffer, OutNumber); // 接收的数据字节数保存在OutNumber变量中
usb_OUT_done(); // 接收的数据保存在UsbOutBuffer缓存区
printf("lailelaodi");
} // 使用USB_SendData库函数可向上位机发送数据
// 调用usb_OUT_done 准备接收下一笔数据
}
}
void sys_init()
{
WTST = 0;//设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
EAXFR = 1; //扩展寄存器(XFR)访问使能
CKCON = 0; //提高访问XRAM速度
P0M1 = 0x30; P0M0 = 0x30; //设置P0.4、P0.5为漏极开路(实验箱加了上拉电阻到3.3V)
P1M1 = 0x32; P1M0 = 0x32; //设置P1.1、P1.4、P1.5为漏极开路(实验箱加了上拉电阻到3.3V), P1.1在PWM当DAC电路通过电阻串联到P2.3
P2M1 = 0x3c; P2M0 = 0x3c; //设置P2.2~P2.5为漏极开路(实验箱加了上拉电阻到3.3V),设置开漏模式需要断开PWM当DAC电路中的R2电阻
P3M1 = 0x53; P3M0 = 0x50; //设置P3.4、P3.6为漏极开路(实验箱加了上拉电阻到3.3V)
// P30/P31和USB的D-/D+共用PIN脚 需要将P30 P31设置为高阻输入模式
P4M1 = 0x3c; P4M0 = 0x3c; //设置P4.2~P4.5为漏极开路(实验箱加了上拉电阻到3.3V)
P5M1 = 0x0c; P5M0 = 0x0c; //设置P5.2、P5.3为漏极开路(实验箱加了上拉电阻到3.3V)
P6M1 = 0xff; P6M0 = 0xff; //设置为漏极开路(实验箱加了上拉电阻到3.3V)
P7M1 = 0x00; P7M0 = 0x00; //设置为准双向口
}
void CMP_Isr() interrupt 21
{
CMPIF = 0; //清中断标志
P40 = !CMPRES; //中断方式读取比较器比较结果
}
noonezero
发表于 2023-10-14 15:15:24
第二十五课:FLASH模拟EEPROM
1.Flash和EEPROM是什么
EEPROM全称“电可擦除可编程只读存储器”。是相对于紫外线擦除的ROM来讲
狭义的EEPROM:特点是可以随机访问和修改任何一个字节。掉电数据不丢失,保存时间长(100年),擦写次数多(100W次)
具有较高的可靠性。电路复杂且成本高。很少有超过512K的
Flash:属于广义的EEPROM,因为它也是电擦除的ROM,为了区别于一般按字节为单位的擦写的EEPROM,就叫它Flash。Flash如果数据不为0xFF,需要擦除之后才能写入
通常单片机里的Flash都用于存放运行代码,在运行过程中不能改变
EEPROM是用来保存用户数据,运行过程中可以改变,比如运行过程中的密码等参数,就需要保存在EEPROM里。
2.内部EEPROM介绍
EEPROM 的写操作只能将字节中的 1 写为 0,当需要将字节中的 0 写为 1,就必须执行扇区擦除操作。
EEPROM 的读/写操作是以 1 字节为单位进行的,而 EEPROM 擦除操作是以 1 扇区( 512 字节)为单位进行
在执行擦除操作时,如果目标扇区中有需要保留的数据,则必须预先将这些数据读取到 RAM中暂存,
待擦除完成后再将保存的数据和需要更新的数据一起再写回
当使用 IAP 寄存器操作 EEPROM 时,不能打开 CACHE功能,否则可能无法访问正确 EEPROM
3.内部EEPROM的简单使用
noonezero
发表于 2023-10-17 06:20:03
第二十五课:FLASH模拟EEPROM
1.Flash和EEPROM是什么
EEPROM全称“电可擦除可编程只读存储器”。是相对于紫外线擦除的ROM来讲
狭义的EEPROM:特点是可以随机访问和修改任何一个字节。掉电数据不丢失,保存时间长(100年),擦写次数多(100W次)
具有较高的可靠性。电路复杂且成本高。很少有超过512K的
Flash:属于广义的EEPROM,因为它也是电擦除的ROM,为了区别于一般按字节为单位的擦写的EEPROM,就叫它Flash。Flash如果数据不为0xFF,需要擦除之后才能写入
通常单片机里的Flash都用于存放运行代码,在运行过程中不能改变
EEPROM是用来保存用户数据,运行过程中可以改变,比如运行过程中的密码等参数,就需要保存在EEPROM里。
2.内部EEPROM介绍
EEPROM 的写操作只能将字节中的 1 写为 0,当需要将字节中的 0 写为 1,就必须执行扇区擦除操作。
EEPROM 的读/写操作是以 1 字节为单位进行的,而 EEPROM 擦除操作是以 1 扇区( 512 字节)为单位进行
在执行擦除操作时,如果目标扇区中有需要保留的数据,则必须预先将这些数据读取到 RAM中暂存,
待擦除完成后再将保存的数据和需要更新的数据一起再写回
当使用 IAP 寄存器操作 EEPROM 时,不能打开 CACHE功能,否则可能无法访问正确 EEPROM
3.内部EEPROM的简单使用
noonezero
发表于 2023-10-17 14:12:01
第二十六课:DS18B20温度传感器
1.DS18B20简介
DS18B20是常用的数字温度传感器,输出数字信号
具有体积小,硬件开销低,抗干扰能力强,精度高的特点
封装多种,可用于不同非极限温度场合
耐磨碰撞,体积小,使用方便
01.单线接口方式,一根线就可以
02.测温范围-55--+125摄氏度,误差1摄氏度
03.工作电源:3.0--5.5V/DC(可以数据线寄生电源)
04.测量结果以9--12位数字量方式串行传送
2.接线方式
单独电源供电
寄生电源供电
3.测温度
可以自定义精度,精度和分辨率对应关系
09位 0.5度
10位 0.25度
11位 0.125度
12位 0.0625度
上电默认12位转换精度
温度对应关系
事件序列
一,初始化
二,ROM (紧跟任何数据交换请求)
三,18B20功能命令 (紧跟任何数据交换请求)
当执行完ROM命令之后,主设备必须回到上述步骤中的第一步
代码:
noonezero
发表于 2023-10-18 11:15:19
本帖最后由 noonezero 于 2023-10-19 06:34 编辑
第二十七课:软件模拟SPI
1.SPI简介
SPI是串行外设接口的缩写,SPI是一种高速的全双工同步通信总线,在芯片的管教上只占用四根线,节约芯片管脚。
MISO:主机输入,从机输出(数据来自从机)
MOSI:主机输出,从机输入(数据来自主机)
SCLK:串行时钟信号,由主机产生发送给从机
SS/CS: 片选信号,主机发送,以控制与哪个从机通信,通常低电平有效信号
2.数据模式
时钟极性(CKP/CPOL)
默认时钟信号是高电平还是低电平
CKP = 0,时钟空闲IDLE为低电平0;
CKP = 1,时钟空闲IDLE为高电平1;
时钟相位(CKE/CPHA)
CPHA = 0,时钟信号SCK的第一个跳变沿采样
CPHA = 1,时钟信号SCK的第二个跳变沿采样
时钟极性和相位共同决定读取数据的方式,比如信号上升沿读取数据还是信号下降沿读取数据
MSB:高位开始读写
LSB:低位开始读写
代码
如果选择的频率低的话,可以按冲哥视频中直接使用
我选择24M,就需要加SPI_Delay函数,否则无法通信