noonezero 发表于 2023-10-19 09:53:49

本帖最后由 noonezero 于 2023-10-25 15:45 编辑

第二十八课:硬件SPI读写FLASH芯片


1.硬件SPI寄存器介绍
引脚切换





寄存器


SPIF:SPI 中断标志位,此标志位需软件方式此位写 1 清零

WCOL:SPI 写冲突标志位,此标志位需软件方式此位写 1 清零

SSIG:SS 引脚功能控制位,确定器件是主机还是从机

SPEN:SPI 使能控制位

DORD:SPI 数据位发送/接收的顺序(0MSB/1LSB)

MSTR:器件主/从模式选择位

CPOL:SPI 时钟极性控制,0为低电平

CPHA:SPI 时钟相位控制

SPR:SPI 时钟频率选择



SPDAT:SPI 发送/接收数据缓冲器


这一节最大的问题就是硬件SPI中对于晶振配置的问题,按冲哥视频11M可以用,24M就不行,或许是SPI速率问题?
模式1硬件我看案例改了,模式2 24M还不行
先跳过,以后填坑
代码:






noonezero 发表于 2023-10-26 06:21:02

第二十九课:SPI读写FLASH芯片


代码:



noonezero 发表于 2023-10-30 06:27:25

本帖最后由 noonezero 于 2023-11-1 08:08 编辑

第三十课:软件模拟IIC


IIC介绍
IIC总线是一种简单、双向二线制同步串行总线,只需要两根线就可以在连接于总线上的器件之间传递消息
简单来说就是一个线来控制时钟(SCL)和一个线来发送数据(SDA)
两个线按照一定的传输协议来进行传输数据。由于只有一根线来读写数据,也就意味着同一时间只能有一个发送设备
(这里我们将产生时钟信号的设备称为主机,一条IIC总线同一时间只会有一个主机)



主机写入数据



主机读取数据



代码:



noonezero 发表于 2023-11-1 09:25:46

本帖最后由 noonezero 于 2023-11-1 10:34 编辑

第三十一课:硬件模拟IIC
STC32G12K128 系列没有超时控制功能

1.与标准 IIC 协议相比较,忽略了两种机制
发送起始信号(START)后不进行仲裁


时钟信号(SCL)停留在低电平时不进行超时检测



2.IIC功能引脚切换




3.配置


ENI2C:IIC 功能使能控制位

MSSL:IIC主从机设定
MSSPEED:总线速度





EMSI:主机模式中断使能控制位

MSCMD:主机命令





WDTA:主机模式时 IIC 数据自动发送允许位





MSBUSY:主机模式时 IIC 控制器状态位(只读)

MSACKI:主机模式时,发送“0011”命令到 I2CMSCR 的 MSCMD 位后所接收到的 ACK 数据。(只读位)

MSACKO:主机模式时,准备将要发送出去的 ACK 信号。当发送“0101”命令到 I2CMSCR 的 MSCMD位后,控制器会自动读取此位的数据当作 ACK 发送到 SDA



代码:



开机读取可以正常读取,+1写入以后在读取就读取失败了
上电再次读取还是ok,问题还在找,找出来填坑





noonezero 发表于 2023-11-1 11:30:42

第三十二课:串口EEPROM芯片数据读写


暂时略过

noonezero 发表于 2023-11-1 11:47:11

第三十三课:PWM基础



波形和相关术语


波形表示信号的形状、形式,这个信号可以是波在物理介质上的移动,也可以是其他物理量的抽象表达形式。
电子行业的波形代指电压在时间基准上的表达形式


有PWM转换器(脉冲宽度调制)和PFM转换器(脉冲频率调制)
PWM转换器,长度不变,改变占空比

PFM转换器,改变频率



术语
幅值:高低电平电压差
正脉宽:高电平时间
负脉宽:低电平时间
周期:高电平+低电平时间
频率:周期的倒数1/周期
占空比:高电平占周期的百分比
死区:两路方波之间高电平之间的时间差
相位差:方波移相


PWM
PWM控制技术就是对脉冲宽度进行调制的技术,即通过一系列的脉冲宽度进行调制,来等效所需的波形(含形状和幅值)


等效电压
占空比*高电平


noonezero 发表于 2023-11-9 06:43:57

本帖最后由 noonezero 于 2023-11-16 09:34 编辑

第三十四课:单通道PWM输出


1.PWM配置流程和寄存器讲解



PWM输出框架示意图 图片太大,转压缩包





代码:
#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#";

#define PWM_ARR 999
#define PWM_CCR 500

// PWMA初始化
// 输出频率:sysclk / (pscr + 1)/(arr + 1) = 22118400 / 1 / (999 + 1) = 22118.4hz = 22.1184khz
// 占空比:ccr/ (arr + 1) * 100% = 500/(999+1) = 50%
void PWMA_Init(void)
{
        // 时钟选择,默认22.1184
       
        // 时基单元选择
        PWMA_PSCRH = 0;                // 1分频
        PWMA_PSCRL = 0;
       
        PWMA_ARRH = (u8)(PWM_ARR >> 8);
        PWMA_ARRL = (u8)PWM_ARR;
       
        PWMA_CCR1H = (u8)(PWM_CCR >> 8);
        PWMA_CCR1L = (u8)PWM_CCR;
       
        // 输入输出引脚配置
        PWMA_ENO = 0x00;        // 使能PWM1通道输出
        PWMA_ENO |= 0x01;
       
        PWMA_PS = 0x00;                // 选择PWM1从P60引脚输出
        PWMA_PS |= (2<<0);// 选择PWM1从P60引脚输出
       
        // 输入输出模式设置
        PWMA_CCER1 = 0x00;
        PWMA_CCMR1 = 0x68;        // PWM模式1,配置置位输出
        PWMA_CCER1 = 0x01;        // 开启输出比较通道
       
        PWMA_BKR = 0x80;        // 使能主输出
        PWMA_CR1 |= 0x01;        // 启动计数器
       
}


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配置完成
       
        P40 = 0;
        P61 = 0;
        PWMA_Init();
       
        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;   //设置为准双向口
}

noonezero 发表于 2023-11-17 09:03:06

本帖最后由 noonezero 于 2023-11-17 10:04 编辑

第三十五课:任意频率和占空比的PWM输出


1.任意频率和占空比的PWM输出
边沿对齐PWM频率 = SYSclk/((PSCR+1)*(ARR+1))
(PSCR+1)*(ARR+1) = SYSclk/边沿对齐PWM频率



PSCR和ARR数值最大65535

设主时钟为24Mhz,需要输出的PWM频率为50HZ,ARR和PSCR取值?10KHZ?
50HZ下
(PSCR+1)*(ARR+1) = 24000000/50 = 480000
(ARR+1) = 480000 / 2/2/2=60000
PSCR = 7
ARR = 59999


10HZ下
(PSCR+1)*(ARR+1) = 24000000/10000 = 2400

PSCR = 0
ARR = 2399



2.互补/同相PWM输出


如何使能互补/同相输出
1.使能ENO寄存器,打开互补输出通道
2.CCERx寄存器打开 比较输出使能


如何设置输出的另一半波形是互补还是同相
1.CCERx寄存器设置比较输出极性



3.带死区的互补PWM输出





死区计算

死区时间计算图表




页: 1 2 3 [4]
查看完整版本: 冲哥STC32G单片机学习笔记