神农鼎 发表于 前天 16:03

帮网友问 SPI

帮网友问 SPI

谁帮我瞅下,这配置SPI是不是有错://usart2 spi
// 定义 SPI 引脚对应的位操作
#define DAC_SPI_SS_PIN      P54
#define DAC_SPI_MOSI_PIN    P40
#define DAC_SPI_MISO_PIN    P41
#define DAC_SPI_SCLK_PIN    P43
// SPI 初始化函数(USART2 SPI 主机模式)
void ADC_SPI_Init(void)
{
    // 第一步:使能访问 XFR(扩展寄存器)
    P_SW2 |= 0x80;      // EAXFR = 1,允许访问 XFR

    // P5.4 推挽输出:P5M1.4=0, P5M0.4=1
    P5M1 &= ~0x10;      // P5M1 bit4 = 0
    P5M0 |= 0x10;       // P5M0 bit4 = 1

    // P4.0 推挽输出:P4M1.0=0, P4M0.0=1
    P4M1 &= ~0x01;
    P4M0 |= 0x01;

    // P4.1 高阻输入:P4M1.1=1, P4M0.1=0
    P4M1 |= 0x02;
    P4M0 &= ~0x02;

    // P4.3 推挽输出:P4M1.3=0, P4M0.3=1
    P4M1 &= ~0x08;
    P4M0 |= 0x08;

    P_SW3 &= ~0x30;      
    P_SW3 |= 0x20;      
    S2CON = 0x10;

    USART2CR1 = 0x10;    // 使能 USART2 的 SPI 模式 (SPMOD=1)
    USART2CR1 &= ~0x40;// DORD=0,先发高位
    USART2CR1 &= ~0x04;// SPSLV=0,主机模式
    USART2CR1 |= 0x00;   // CPOL=0, CPHA=0
    USART2CR4 = 0x00;    // SPICKS=00,SPI 速度为 SYSCLK/4
    USART2CR1 |= 0x08;   // SPIEN=1,使能 SPI 功能   

    DAC_SPI_SS_PIN = 1;
}// SPI 发送/接收一字节(主机模式)
voidADC_SendByte(unsigned char dat)
{   
   // 写 S2BUF 启动发送
    S2BUF = dat;
    // 等待发送完成——检查 S2TI 标志(不是 SPSTAT!)
    while(!(S2CON & 0x02));   // 等待 S2TI=1
    S2CON &= ~0x02;            // 软件清零 S2TI   
}


// 向 TLV5638 写入 16 位数据(高位先行)
static void TLV5638_Write_Data(u16 dat)
{
    DAC_SPI_SS_PIN = 0;               // 拉低 SS,选中从机

    ADC_SendByte((u8)(dat >> 8));       // 发送高 8 位
    ADC_SendByte((u8)(dat));            // 发送低 8 位

    DAC_SPI_SS_PIN = 1;               // 拉高 SS,释放从机
}

神农鼎 发表于 前天 16:03


神农鼎 发表于 前天 16:04

<p>好的,我来帮您仔细检查一下这段 SPI 配置代码。首先我需要确认您使用的是哪一款 STC 单片机型号?从代码中看,您使用了 <code>USART2CR1</code>、<code>USART2CR4</code>、<code>P_SW3</code> 等寄存器,这看起来像是 <strong>STC8H</strong> 或 <strong>Ai8H</strong> 系列(或 STC32G 系列)的 USART 同步 SPI 模式。</p>
<p>不过,在深入分析之前,我需要先确认几个关键信息,因为您的问题中缺少了芯片型号这个关键条件:</p>
<p><strong>请您补充以下信息:</strong></p>
<ol>
<li><strong>您使用的是哪一款具体的 STC 单片机型号?</strong>(例如 STC8H8K64U、STC8H1K08、Ai8H 等)</li>
<li><strong>您期望的 SPI 时钟频率是多少?</strong>(或者说您的主频 SYSCLK 是多少?)</li>
</ol>
<p>有了这些信息,我才能对照手册精确地帮您排查寄存器配置是否正确。</p>
<hr />
<p>不过,即便没有型号,我也可以先根据代码本身指出几个<strong>明显的问题</strong>:</p>
<h3>问题 1:<code>P_SW3</code> 位操作逻辑有误</h3>
<pre><code class="language-c">P_SW3 &amp;= ~0x30;      // 清除 bit4、bit5
P_SW3 |= 0x20;       // 设置 bit5 = 1 → 即选择 01 选项
</code></pre>
<p><code>P_SW3</code> 的 bit4、bit5 用于选择 USART2 的引脚映射。<code>0x20</code> 对应 <code>0b10_0000</code>,即 bit5=1、bit4=0,选择的是 **选项 2**。</p>
<p>但您定义的引脚是:</p>
<ul>
<li>SS → P5.4</li>
<li>MOSI → P4.0</li>
<li>MISO → P4.1</li>
<li>SCLK → P4.3</li>
</ul>
<p><strong>请对照您芯片手册中 &quot;USART2 功能脚切换&quot; 的表格</strong>,确认 <code>P_SW3</code> 的 <code></code> 设置是否真的能将这些引脚映射为 USART2 的 SPI 功能。不同选项对应的引脚组不同,<strong>这里很可能选错了映射组</strong>。</p>
<h3>问题 2:<code>USART2CR1</code> 的 CPOL/CPHA 配置写法冗余</h3>
<pre><code class="language-c">USART2CR1 |= 0x00;   // CPOL=0, CPHA=0
</code></pre>
<p><code>|= 0x00</code> 是空操作,虽然不会出错,但这样写容易让人误解。建议直接写成:</p>
<pre><code class="language-c">USART2CR1 &amp;= ~0x03;// CPOL=0, CPHA=0 (bit0=CPHA, bit1=CPOL)
</code></pre>
<h3>问题 3:等待发送完成标志位可能不对</h3>
<pre><code class="language-c">while(!(S2CON &amp; 0x02));   // 等待 S2TI=1
</code></pre>
<p><code>S2CON.1</code> 确实是 S2TI 位(发送中断标志),<strong>这个是对的</strong>。但需要注意:在 SPI 模式下,发送完成同时也意味着接收完成(因为 SPI 是同步全双工),如果您需要读取接收到的数据,应该在清零 S2TI 之前先读取 <code>S2BUF</code>。</p>
<h3>问题 4:缺少接收数据的处理</h3>
<p>您的 <code>ADC_SendByte</code> 函数只发送不接收。如果 TLV5638 是只写器件那没问题,但如果后续需要读取从机数据,这个函数需要改造为同时收发。</p>
<hr />
<p><strong>请您先告诉我具体的芯片型号</strong>,我就可以查手册确认 <code>P_SW3</code> 的引脚映射是否正确,以及 <code>USART2CR1</code>/<code>USART2CR4</code> 的寄存器位定义是否与您的芯片匹配,然后给出完整的修正代码。</p>
<hr />
<p><a href="https://www.stcaimcu.com/plugin.php?id=twpx_xunsearch&amp;mod=forum&amp;q=%E8%B0%81%E5%B8%AE%E6%88%91%E7%9E%85%E4%B8%8B%20%E8%BF%99%E9%85%8D%E7%BD%AESPI%E6%98%AF%E4%B8%8D%E6%98%AF%E2%80%A6&amp;f=_all&amp;m=yes&amp;syn=yes&amp;s=relevance&amp;fid=0">🔍 搜索 &quot;谁帮我瞅下 这配置SPI是不是…&quot;</a></p>
<p>⏱️ 查找用时 0.9s | 总回答用时 9.0s</p>
页: [1]
查看完整版本: 帮网友问 SPI