<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:wfw="http://wellformedweb.org/CommentAPI/">
<channel>
<title>小夏的猪窝 - 嵌入式</title>
<link>https://blog.x-tools.top/tag/%E5%B5%8C%E5%85%A5%E5%BC%8F/</link>
<atom:link href="https://blog.x-tools.top/feed/tag/%E5%B5%8C%E5%85%A5%E5%BC%8F/" rel="self" type="application/rss+xml" />
<language>zh-CN</language>
<description></description>
<lastBuildDate>Wed, 16 Nov 2022 10:05:00 +0000</lastBuildDate>
<pubDate>Wed, 16 Nov 2022 10:05:00 +0000</pubDate>
<item>
<title>STM32 - DS18B20驱动</title>
<link>https://blog.x-tools.top/archives/77/</link>
<guid>https://blog.x-tools.top/archives/77/</guid>
<pubDate>Wed, 16 Nov 2022 10:05:00 +0000</pubDate>
<dc:creator>小夏</dc:creator>
<description><![CDATA[&lt;!--[toc]--&gt;DS18B20简单介绍一下，查询数据手册可以知道：一个温度传感器，测量范围在-55°C ~ +125°C，仅需要单片机一个IO接口，寄生电源模式（没玩过），宽...]]></description>
<content:encoded xml:lang="zh-CN"><![CDATA[
<p>&lt;!--[toc]--&gt;</p><h1>DS18B20</h1><p>简单介绍一下，查询数据手册可以知道：<br>一个温度传感器，<br>测量范围在<code>-55°C ~ +125°C</code>，<br>仅需要单片机一个IO接口，<br>寄生电源模式（没玩过），<br>宽电压范围 <code>+3.0V ~ +5.5V</code>。</p><h2>通信时序图</h2><p><strong>时序图</strong>：<br><img src="http://cdn.x-tools.top/MarkDownImg/2022111663695527.png" alt="" title=""><br><strong>参数表</strong>：<br><img src="http://cdn.x-tools.top/MarkDownImg/2022111663808258.png" alt="" title=""></p><p>如图有：</p><ul><li>写指令时序</li><li>读数据时序</li><li>重置重置时序</li><li>检测时序</li></ul><h3>写指令函数</h3><p><img src="http://cdn.x-tools.top/MarkDownImg/2022111663874886.png" alt="" title=""><br>观察写指令时序图，<br>首先将电平从低拉高后等待<code>tREC</code>的时间，时间查看参数表中最小为1us，<br>最小延迟1us是为了使电平稳定。<br>延迟1-2us后，<br>将电平改变成有效数据位的高低电平后，观察时序图<code>tSLOT</code>一个周期时间在60-120us之间，所以我们延迟60us即可。<br>如部分代码(其中使用了部分宏定义，若需要更全的文件，请跳至最后下载附件即可)：</p><pre><code class="lang-C">/*******************************************************************************
  * 函数名：DS18B20_WriteByte
  * 功  能：向DS18B20写入一个字节
  * 参  数：u8Data:要写入的数据
  * 返回值：无
  * 说  明：
*******************************************************************************/
void DS18B20_WriteByte(uint8_t u8Data)
{
    uint8_t tempIndex,tempData;
    DS18B20_DQModeOutput();//设置为输出
    for (tempIndex = 1; tempIndex &lt;= 8; tempIndex++)
    {
        tempData = (u8Data &amp; 0x01);
        u8Data &gt;&gt;= 1;
        if (tempData == 1)
        {
            DS18B20_DQReset();//低电平
            delay_us(2);
            DS18B20_DQSet();//高电平
            delay_us(60);//延时60us
        }else
        {
            DS18B20_DQReset();//低电平
            delay_us(60);//延时60us
            DS18B20_DQSet();//高电平
            delay_us(2);
        }        
    }
}</code></pre><h3>读数据函数</h3><p><img src="http://cdn.x-tools.top/MarkDownImg/2022111664447699.png" alt="" title=""><br>同样和写指令时序一样，一个周期为60us到120us内，读取电平的有效数据时间在15us内都是有效的，<br>所以选择在12us后读取数据的电平，因为一个周期还没结束，所以多等待50us结束读取。<br><strong>拉低电平 -&gt; 等待2us -&gt; 拉高电平 -&gt; 等待12us -&gt; 读取电平 -&gt; 等待50us</strong><br>部分代码(其中使用了部分宏定义，若需要更全的文件，请跳至最后下载附件即可)：</p><pre><code class="lang-C">/*******************************************************************************
  * 函数名：DS18B20_ReadByte
  * 功  能：从DS18B20读取一个字节
  * 参  数：无
  * 返回值：u8Data读出的数据
  * 说  明：无
*******************************************************************************/
uint8_t DS18B20_ReadByte(void)
{
    uint8_t i,j, u8Ddata = 0;
    
    for (i = 1; i &lt;= 8; i++)
    {        
        j = DS18B20_ReadBit();
        u8Ddata = (j &lt;&lt; 7) | (u8Ddata &gt;&gt; 1);
    }    
    return u8Ddata;
}</code></pre><h2>附件</h2><p>该附件包含：</p><ul><li>DS18B20.c 驱动文件</li><li>DS18B20.h 驱动头文件</li><li>maxim-ds18b20.pdf 传感器文档</li></ul><p>注意：此驱动使用的延迟方法利用定时器作为延迟，可自行更改。</p><p>附件：<a href="https://b.x-tools.top/typecho/uploads/2022/11/3611929055.zip">DS18B20 STM32驱动.zip</a></p>
]]></content:encoded>
<slash:comments>0</slash:comments>
<comments>https://blog.x-tools.top/archives/77/#comments</comments>
<wfw:commentRss>https://blog.x-tools.top/feed/tag/%E5%B5%8C%E5%85%A5%E5%BC%8F/</wfw:commentRss>
</item>
<item>
<title>嵌入式 - 时序图写代码</title>
<link>https://blog.x-tools.top/archives/75/</link>
<guid>https://blog.x-tools.top/archives/75/</guid>
<pubDate>Wed, 16 Nov 2022 06:27:00 +0000</pubDate>
<dc:creator>小夏</dc:creator>
<description><![CDATA[&lt;!--[toc]--&gt;IIC，I2（方）C ，利用总线SCL、SDA，写时序读取数据时序图：datasheet总线的概念总线占两线：SCL、SDA为什么是总线：可以在总线上连接很多...]]></description>
<content:encoded xml:lang="zh-CN"><![CDATA[
<p>&lt;!--[toc]--&gt;</p><blockquote>IIC，I2（方）C ，利用总线SCL、SDA，写时序读取数据</blockquote><p>时序图：datasheet</p><h1>总线的概念</h1><p>总线占两线：SCL、SDA</p><p>为什么是总线：可以在总线上连接很多IIC设备，这样可以节省2个io口</p><h1>从机地址</h1><p>从机地址：身份证、与生俱来，生产厂家规定</p><p>当总线发送IIC的从机地址后，此IIC设备将返回一个应答信号</p><p>从机地址是IIC设备独有的，可以可能被自己定义。</p><p>从机地址一般为7位，通常情况下（24C02举例）：</p><ul><li>前四位固定</li><li>后三位自定义</li><li><p>最后一位：方向位 控制读写</p><ul><li>为0：主机写设备操作</li><li>为1：主机读设备操作</li></ul></li></ul><p>以上8位构成了寻址字节</p><h1>寻址字节</h1><blockquote>单片机是怎么发送寻址字节</blockquote><p>IIC只有一位的数据接口，他只能一位一位的发送，所以IIC是<strong>串行发送</strong></p><ol><li>首先建立通信需要向总线发送一个从机地址，并且最后一位方向位为0</li><li>等待设备的应答信号，就能继续发送代码</li></ol><h1>观察时序 写代码 24C02</h1><p><img src="http://cdn.x-tools.top/MarkDownImg/2022111547162589.png" style="height:130px;" /><br>上图红框中为寻址字节。</p><ul><li>中间的存储单元地址为存储器存放数据的地址</li><li>后方的数据为设备向单片机发送的数据</li></ul><p><img src="http://cdn.x-tools.top/MarkDownImg/2022111547536418.png" style="height:330px;" /><br>上图红框部分与下图绿框部分一致。</p><p><img src="http://cdn.x-tools.top/MarkDownImg/2022111547581705.png" alt="" title=""></p><ul><li><strong>MSB</strong>意为数据 字节最高位</li><li><strong>ACK</strong>意为应答信号</li></ul><p><img src="http://cdn.x-tools.top/MarkDownImg/2022111547707103.png" alt="" title=""></p><h2>启动START函数</h2><p><img src="http://cdn.x-tools.top/MarkDownImg/2022111547786735.png" alt="" title=""></p><p>带有参数的时序图</p><p><strong>首先分析启动部分（START CONDITION）：</strong></p><p><strong>SCL</strong>：保持一段时间的高电平</p><p><img src="http://cdn.x-tools.top/MarkDownImg/2022111547862105.png" alt="" title=""></p><p><strong>SDA</strong>：</p><p><img src="http://cdn.x-tools.top/MarkDownImg/2022111547908780.png" alt="" title=""></p><p>如图意思为，使SDA保持高电平一段时间（tCHDX）</p><p><img src="http://cdn.x-tools.top/MarkDownImg/2022111550230692.png" alt="" title=""></p><p>这样写代码即可。</p><p>接下来继续分析SDA：</p><p><img src="http://cdn.x-tools.top/MarkDownImg/2022111550314721.png" alt="" title=""></p><p>以上一个START启动阶段就写完了。</p><p><strong>tCHCL：高时钟脉冲宽度</strong></p><h2>寻址字节发送</h2><p>每经过一个SCL的方波周期，SDA就要发送一个数据</p><p>其SCL经过一个高脉冲信号（由低电平转为高电平），IIC设备都会检测SDA信号</p><p>那么就要先将SCL从高变为低，这样才会向设备发送一个高脉冲信号</p><ul><li>发送时，需要在SCL发送高脉冲信号前改变SDA的值后，才能有效的正确的发送读取。</li><li>也就是当SCL处于低电平时改变SDA信号直至信号改变成功后，再将SCL调整到高电平。</li></ul><p>SCL从低电平转换为高电平结束的时间成为<code>时钟周期</code></p><hr><p><img src="http://cdn.x-tools.top/MarkDownImg/2022111553054275.png" alt="" title=""></p><p>上图中<strong>tCLDX</strong>表明：当SCL变为0后，SDA电平转换的时间</p><p>上图中<strong>tDXCX</strong>为：输入转换到时钟转换 意思为：<code>SDA电平转换后需要经过一段时间才能让SCL电平置为高电平</code></p><p>因为<strong>tCHCL：低时钟脉冲宽度</strong> 中的时间包含 <strong>tDXCX</strong>，所以我们只需要考虑前者的时间间隔即可。</p><h2>应答信号</h2><p><img src="http://cdn.x-tools.top/MarkDownImg/2022111552349032.png" alt="" title=""></p><p>当到达第九个时钟周期时，需要将SDA置为高电平，用于准备接受应答信号。</p><ul><li>当设备发送了应答信号后，就将SDA引脚的电平拉低，置为低电平。</li><li>那么当SDA为0时，设备就回应了单片机的寻址地址指令，如图循环判断即可做到等待。</li></ul><p><img src="http://cdn.x-tools.top/MarkDownImg/2022111552493824.png" alt="" title=""></p><hr><p><strong>等待应答，不是应该先把SCL拉低，然后SDA拉高，然后再拉高SCL读取SDA信号是否被拉低，因为在SCL为高电平的时候SDA电平不能变化</strong></p><p><img src="http://cdn.x-tools.top/MarkDownImg/2022111554004982.png" alt="" title=""></p><h2>STOP停止函数</h2><p><img src="http://cdn.x-tools.top/MarkDownImg/2022111554301630.png" alt="" title=""></p><p>观察时序图，初始都为0，SCL为1 SDA需要在一段时间后调整至高电平即可。</p><p><img src="http://cdn.x-tools.top/MarkDownImg/2022111554286033.png" alt="" title=""></p>
]]></content:encoded>
<slash:comments>0</slash:comments>
<comments>https://blog.x-tools.top/archives/75/#comments</comments>
<wfw:commentRss>https://blog.x-tools.top/feed/tag/%E5%B5%8C%E5%85%A5%E5%BC%8F/</wfw:commentRss>
</item>
<item>
<title>ESP32开发版 SPI接口查询记录</title>
<link>https://blog.x-tools.top/archives/72/</link>
<guid>https://blog.x-tools.top/archives/72/</guid>
<pubDate>Fri, 04 Nov 2022 09:38:00 +0000</pubDate>
<dc:creator>小夏</dc:creator>
<description><![CDATA[&lt;!--[toc]--&gt;ESP32 SPI通信研究笔记使用ESP32加SPI通信连接TFT2.4寸屏幕 实现屏幕最基本的输出材料准备GOOUUU-ESP32开发版，某宝购入。2.4寸...]]></description>
<content:encoded xml:lang="zh-CN"><![CDATA[
<p>&lt;!--[toc]--&gt;</p><h1>ESP32 SPI通信研究笔记</h1><p>使用ESP32加SPI通信连接TFT2.4寸屏幕 实现屏幕最基本的输出</p><h2>材料准备</h2><ul><li>GOOUUU-ESP32开发版，某宝购入。</li><li>2.4寸TFT液晶显示屏裸屏 驱动：ST7789V，某宝购入。</li><li>[可选] 立创EDA自己画的装裸屏用的PCB板<img src="http://cdn.x-tools.top/MarkDownImg/202211461011338.png" alt="" title=""><br>如果你买的是裸屏，就需要按照引脚、原理图自己画个底板。</li></ul><h2>资料准备</h2><p>这里资料都是网上找的。</p><ul><li><a href="https://file.x-tools.top/d/%E5%85%B1%E4%BA%AB%E8%B5%84%E6%BA%90/%E5%B5%8C%E5%85%A5%E5%BC%8F/ESP32/2.4TFT7PIspi-GMT024-01.rar">2.4TFT7PIspi-GMT024-01.rar</a><br>购入TFT屏幕时附赠的案例，已修改ESP32对应功能引脚。</li><li>ESP32功能引脚图、以及IDE中数字引脚与功能的对应图。<a href="https://file.x-tools.top/%E5%85%B1%E4%BA%AB%E8%B5%84%E6%BA%90/%E5%B5%8C%E5%85%A5%E5%BC%8F/ESP32">链接</a><br><img src="http://cdn.x-tools.top/MarkDownImg/202211461813381.png" alt="" title=""><br><img src="http://cdn.x-tools.top/MarkDownImg/202211461828351.png" alt="" title=""></li></ul><h2>SPI通信</h2><p><code>SPI</code>通信是一种全双工、高速的通信方式，其通信速度和<code>IIC</code>相比是遥遥领先...<br>成功建立SPI通信至少需要4个引脚：MISO、MOSI、SCLK、CS，引脚作用分别是：主设备数据输入，从设备数据输出、主设备数据输出，从设备数据输入、时钟信号，由主设备产生、从设备片选信号，由主设备控制。</p><pre><code class="lang-c">MISO：主设备数据输入，从设备数据输出;
MOSI：主设备数据输出，从设备数据输入;
SCLK：时钟信号，由主设备产生;
CS：从设备片选信号，由主设备控制;</code></pre><h2>操作</h2><p>本次TFT屏幕裸屏引出的引脚分别是：CS、DC、RST、SDA、SCL以及供电、供地。</p><ol><li><p>依次连接相关引脚：</p><pre><code class="lang-c">SCK - 22 - G22
SDA - 21 - G21
RST - 15 - G15
DC  - 32 - G32
CS  - 14 - G14</code></pre></li><li>连接后，验证上传程序，就可以看见效果...如图：<br><img src="http://cdn.x-tools.top/MarkDownImg/202211463389721.png" alt="" title=""></li></ol><h2>完结</h2><p>本文只是测试TFT引脚连接对应ESP32功能引脚，并不是一个符合规范的程序示例。<br>连接成功后，可以尝试使用更多外置的库文件，来使用此TFT屏幕。<br>另外，嘉立创免费打板，6。</p>
]]></content:encoded>
<slash:comments>0</slash:comments>
<comments>https://blog.x-tools.top/archives/72/#comments</comments>
<wfw:commentRss>https://blog.x-tools.top/feed/tag/%E5%B5%8C%E5%85%A5%E5%BC%8F/</wfw:commentRss>
</item>
<item>
<title>FPGA - 模块整合新1</title>
<link>https://blog.x-tools.top/archives/34/</link>
<guid>https://blog.x-tools.top/archives/34/</guid>
<pubDate>Sun, 12 Jun 2022 13:34:00 +0000</pubDate>
<dc:creator>小夏</dc:creator>
<description><![CDATA[&lt;!--[toc]--&gt;本文存在过多代码行！如果出现代码堆叠，请按F5刷新网页即可~其它知识点在Verilog HDL中，使用关键词posedge表示上升沿触发，使用关键词neged...]]></description>
<content:encoded xml:lang="zh-CN"><![CDATA[
<p>&lt;!--[toc]--&gt;</p><blockquote>本文存在过多代码行！如果出现代码堆叠，请按F5刷新网页即可~</blockquote><h1>其它知识点</h1><ul><li>在Verilog HDL中，使用关键词posedge表示上升沿触发，使用关键词negedge表示下降沿触发。</li><li>开发版中单个数码管是共阴级，4位数码管相反 是 共阳极</li><li>开发版中8*8点阵屏是共阳极</li><li>开发版中 拨码开关 拨到左边是off 为1</li></ul><h1>引脚绑定</h1><table><thead><tr><th align="center">名称</th><th align="center">引脚编号</th></tr></thead><tbody><tr><td align="center"><code>clk - 24M晶振</code></td><td align="center">18</td></tr><tr><td align="center">LED1 - 灯</td><td align="center">29</td></tr><tr><td align="center">LED2 - 灯</td><td align="center">30</td></tr><tr><td align="center">LED3 - 灯</td><td align="center">31</td></tr><tr><td align="center">LED4 - 灯</td><td align="center">32</td></tr><tr><td align="center">LED5 - 灯</td><td align="center">37</td></tr><tr><td align="center">LED6 - 灯</td><td align="center">38</td></tr><tr><td align="center">LED7 - 灯</td><td align="center">39</td></tr><tr><td align="center">LED8 - 灯</td><td align="center">40</td></tr><tr><td align="center">BUZZ - 蜂鸣器</td><td align="center">41</td></tr><tr><td align="center">K1 - 按键</td><td align="center">61</td></tr><tr><td align="center">K2 - 按键</td><td align="center">62</td></tr><tr><td align="center">K3 - 按键</td><td align="center">63</td></tr><tr><td align="center">K4 - 按键</td><td align="center">66</td></tr><tr><td align="center">K5 - 按键</td><td align="center">67</td></tr><tr><td align="center">K6 - 按键</td><td align="center">68</td></tr><tr><td align="center">K7 - 按键</td><td align="center">69</td></tr><tr><td align="center">K8 - 按键</td><td align="center">70</td></tr><tr><td align="center">SW0 - 拨码开关</td><td align="center">71</td></tr><tr><td align="center">SW1 - 拨码开关</td><td align="center">72</td></tr><tr><td align="center">SW2 - 拨码开关</td><td align="center">73</td></tr><tr><td align="center">SW3 - 拨码开关</td><td align="center">74</td></tr><tr><td align="center">SW4 - 拨码开关</td><td align="center">75</td></tr><tr><td align="center">SW5 - 拨码开关</td><td align="center">76</td></tr><tr><td align="center">SW6 - 拨码开关</td><td align="center">77</td></tr><tr><td align="center">SW7 - 拨码开关</td><td align="center">78</td></tr><tr><td align="center">SEG_A - 一位数码管 0</td><td align="center">124</td></tr><tr><td align="center">SEG_B - 一位数码管 1</td><td align="center">123</td></tr><tr><td align="center">SEG_C - 一位数码管 2</td><td align="center">121</td></tr><tr><td align="center">SEG_D - 一位数码管 3</td><td align="center">120</td></tr><tr><td align="center">SEG_E - 一位数码管 4</td><td align="center">119</td></tr><tr><td align="center">SEG_F - 一位数码管 5</td><td align="center">125</td></tr><tr><td align="center">SEG_G - 一位数码管 6</td><td align="center">127</td></tr><tr><td align="center">SEG_H - 一位数码管 7</td><td align="center">122</td></tr><tr><td align="center">seg0 - 四位数码管显示口</td><td align="center">118</td></tr><tr><td align="center">seg1 - 四位数码管显示口</td><td align="center">117</td></tr><tr><td align="center">seg2 - 四位数码管显示口</td><td align="center">114</td></tr><tr><td align="center">seg3 - 四位数码管显示口</td><td align="center">113</td></tr><tr><td align="center">seg4 - 四位数码管显示口</td><td align="center">112</td></tr><tr><td align="center">seg5 - 四位数码管显示口</td><td align="center">111</td></tr><tr><td align="center">seg6 - 四位数码管显示口</td><td align="center">110</td></tr><tr><td align="center">seg7 - 四位数码管显示口</td><td align="center">109</td></tr><tr><td align="center">sl0 - 四位数码管位选口</td><td align="center">108</td></tr><tr><td align="center">sl1 - 四位数码管位选口</td><td align="center">107</td></tr><tr><td align="center">sl2 - 四位数码管位选口</td><td align="center">106</td></tr><tr><td align="center">sl3 - 四位数码管位选口</td><td align="center">105</td></tr><tr><td align="center">ldoa0 - 点阵位码输出口</td><td align="center">5</td></tr><tr><td align="center">ldoa1 - 点阵位码输出口</td><td align="center">6</td></tr><tr><td align="center">ldoa2 - 点阵位码输出口</td><td align="center">7</td></tr><tr><td align="center">ldoa3 - 点阵位码输出口</td><td align="center">8</td></tr><tr><td align="center">ldoa4 - 点阵位码输出口</td><td align="center">11</td></tr><tr><td align="center">ldoa5 - 点阵位码输出口</td><td align="center">12</td></tr><tr><td align="center">ldoa6 - 点阵位码输出口</td><td align="center">13</td></tr><tr><td align="center">ldoa7 - 点阵位码输出口</td><td align="center">14</td></tr><tr><td align="center">ldob0 - 点阵数据输出口</td><td align="center">15</td></tr><tr><td align="center">ldob1 - 点阵数据输出口</td><td align="center">16</td></tr><tr><td align="center">ldob2 - 点阵数据输出口</td><td align="center">21</td></tr><tr><td align="center">ldob3 - 点阵数据输出口</td><td align="center">22</td></tr><tr><td align="center">ldob4 - 点阵数据输出口</td><td align="center">23</td></tr><tr><td align="center">ldob5 - 点阵数据输出口</td><td align="center">24</td></tr><tr><td align="center">ldob6 - 点阵数据输出口</td><td align="center">27</td></tr><tr><td align="center">ldob7 - 点阵数据输出口</td><td align="center">28</td></tr></tbody></table><h1>分频模块</h1><blockquote><p>if(count==6000000) //0.5s周期</p><p>if(count==12000000) //1s周期</p></blockquote><pre><code class="lang-verilog">module divclk(clkin,clkout);
    input clkin;
    output clkout;
    reg clkout;
    reg[25:0] count;
    always@(posedge clkin)
    begin
       count=count+1;
       if(count==6000000) //0.5s周期
       begin
         clkout=~clkout;
         count=0;
      end
    end
endmodule</code></pre><h1>Flag计数</h1><pre><code class="lang-verilog">module flagcount(clkin,flagout);
    input clkin;
    output[3:0] flagout;
    reg[3:0] flagout;
    always@(posedge clkin)
    begin
        flagout = flagout+1;
    end
endmodule</code></pre><h1>四个数码管显示相同数</h1><pre><code class="lang-verilog">module seg4(flagin,seg,sl);
    input[3:0] flagin;
    output[7:0] seg;
    output[3:0] sl;
    reg[7:0] seg;
    reg[3:0] sl;
    
    always
        sl=4'b0000;
        
    always@(flagin)
    begin
        case(flagin)
            4'h0:seg=8'hc0;//0
            4'h1:seg=8'hf9;//1
            4'h2:seg=8'ha4;//2
            4'h3:seg=8'hb0;//3
            4'h4:seg=8'h99;//4
            4'h5:seg=8'h92;//5
            4'h6:seg=8'h82;//6
            4'h7:seg=8'hf8;//7
            4'h8:seg=8'h80;//8
            4'h9:seg=8'h90;//8
            4'ha:seg=8'h88;//a
            4'hb:seg=8'h83;//b
            4'hc:seg=8'hc6;//c
            4'hd:seg=8'ha1;//d
            4'he:seg=8'h86;//e
            4'hf:seg=8'h8e;//f
        endcase
    end
endmodule</code></pre><h1>四位数码管分别显示</h1><pre><code class="lang-verilog">/*
 * 四位数码管显示三位不同数字
 * clk进24M
 */
module seg4Show3(clk,datain,slout,segout);
    input clk;
    input[9:0] datain;
    output[3:0] slout;
    output[7:0] segout;

    reg[3:0] disp_dat;
    reg[3:0] sl_reg;
    reg[7:0] seg_reg;
    reg[36:0] count;

    always@(posedge clk)
        count = count + 1;
    
    always@(count[14:13])
    begin
        case(count[14:13])
            2'h0:begin
                disp_dat = 4'b0001;
                sl_reg = 4'b1111;
            end
            2'h1:begin
                disp_dat = datain/100;
                sl_reg = 4'b1101;
            end
            2'h2:begin
                disp_dat = (datain%100)/10;
                sl_reg = 4'b1011;
            end
            2'h3:begin
                disp_dat = datain%10;
                sl_reg = 4'b0111;
            end
        endcase
    end
    
    always@(disp_dat)
    begin
        case(disp_dat)
            4'h0:seg_reg=8'hc0;//0
            4'h1:seg_reg=8'hf9;//1
            4'h2:seg_reg=8'ha4;//2
            4'h3:seg_reg=8'hb0;//3
            4'h4:seg_reg=8'h99;//4
            4'h5:seg_reg=8'h92;//5
            4'h6:seg_reg=8'h82;//6
            4'h7:seg_reg=8'hf8;//7
            4'h8:seg_reg=8'h80;//8
            4'h9:seg_reg=8'h90;//8
            4'ha:seg_reg=8'h88;//a
            4'hb:seg_reg=8'h83;//b
            4'hc:seg_reg=8'hc6;//c
            4'hd:seg_reg=8'ha1;//d
            4'he:seg_reg=8'h86;//e
            4'hf:seg_reg=8'h8e;//f
        endcase
    end
    assign segout = seg_reg;
    assign slout = sl_reg;

endmodule</code></pre><h1>按键防抖并且计数</h1><pre><code class="lang-verilog">/*
 * 按键消抖 分频处理
 */
module divclk24(clkin,clkout);
    input clkin;
    output clkout;
    reg clkout;
    reg[25:0] count;
    always@(posedge clkin)
    begin
       count=count+1;
       if(count==240000)
       begin
         clkout=~clkout;
         count=0;
      end
    end
endmodule

/*
 * clkin 分频处理后的信号
 * keyin 按键按下的信号标志
 * out 输出的计数标志 这里是10位 可以改成1位
 */
module getkey(clkin,keyin,out);
    input clkin;
    input keyin;
    output[9:0] out;
    reg[9:0] out;
    reg keyout;
    
    always@(posedge clkin)
        keyout=keyin;

    always@(negedge keyout)
    begin
       out=out+1;
       if(out==1000)
       begin
         out=0;
      end
    end
endmodule</code></pre><h1>1位Seg数码管 显示百位数字</h1><pre><code class="lang-verilog">/* 
 * 共阴数码管
 */
module display(datain,flagin,segout);
    input[9:0] datain;
    input[1:0] flagin;
    output[7:0] segout;
    reg[7:0] segout;

    always@(datain)
    begin
       case(flagin)
            2'd0:
           case(datain/100)
                0:segout=8'h3f;//0
                1:segout=8'h06;//1
                2:segout=8'h5b;//2
                3:segout=8'h4f;//3
                4:segout=8'h66;//4
                5:segout=8'h6d;//5
                6:segout=8'h7d;//6
                7:segout=8'h07;//7
                 8:segout=8'h7f;//8
                 9:segout=8'h6f;//9
                 default:segout=8'h0;
            endcase
          2'd1:
           case((datain/10)%10)
                0:segout=8'h3f|8'h80;//0
                1:segout=8'h06|8'h80;//1
                2:segout=8'h5b|8'h80;//2
                3:segout=8'h4f|8'h80;//3
                4:segout=8'h66|8'h80;//4
                5:segout=8'h6d|8'h80;//5
                6:segout=8'h7d|8'h80;//6
                7:segout=8'h07|8'h80;//7
                 8:segout=8'h7f|8'h80;//8
                 9:segout=8'h6f|8'h80;//9
                default:segout=8'h0;
           endcase
         2'd2:
           case(datain%10)
                0:segout=8'h3f;//0
                1:segout=8'h06;//1
                2:segout=8'h5b;//2
                3:segout=8'h4f;//3
                4:segout=8'h66;//4
                5:segout=8'h6d;//5
                6:segout=8'h7d;//6
                7:segout=8'h07;//7
                 8:segout=8'h7f;//8
                 9:segout=8'h6f;//9
                default:segout=8'h0;
           endcase
        endcase
    end
endmodule
</code></pre><h1>8*8点阵显示汉字</h1><pre><code class="lang-verilog">/*
 * 点阵显示 4个汉字 '上''下''中''大0'
 * clkinshow：进24M时钟信号，用于刷新上电
 * flagin：进显示汉字间隔，处理过的计数标志
 * ldoa,ldob：出点阵的位码输出口、数据输出口
 *
 * Tip：里面的count[14:12]，是刷新上电的间隔，应该非常小，可自行设置
 * case(flagin)下面分支可以改成自己的汉字编码
 */
module Showmatrix(clkinshow,flagin,ldoa,ldob);
    output[7:0] ldoa,ldob;
    input[1:0] flagin;
    input clkinshow;
    
    reg[7:0] ldoa,ldob;
    reg[32:0] count;
    
    always@(posedge clkinshow)
        count = count+1;
    
    always@(count[14:12])
    begin
    case(count[14:12])//上电
            3'h0:ldoa=8'hfe;
            3'h1:ldoa=8'hfd;
            3'h2:ldoa=8'hfb;
            3'h3:ldoa=8'hf7;
            3'h4:ldoa=8'hef;
            3'h5:ldoa=8'hdf;
            3'h6:ldoa=8'hbf;
            3'h7:ldoa=8'h7f;
        endcase
    end
    
    always@(count[14:12])
    begin
        case(flagin)
        2'b00:
            begin
                case(count[14:12])//上
                    3'h0:ldob=8'hf7;
                    3'h1:ldob=8'hf7;
                    3'h2:ldob=8'hc7;
                    3'h3:ldob=8'hf7;
                    3'h4:ldob=8'hf7;
                    3'h5:ldob=8'hf7;
                    3'h6:ldob=8'h80;
                    3'h7:ldob=8'hff;
                endcase
            end
        2'b01:
            begin
                case(count[14:12])//中
                    3'h0:ldob=8'hf7;
                    3'h1:ldob=8'hf7;
                    3'h2:ldob=8'h80;
                    3'h3:ldob=8'hb6;
                    3'h4:ldob=8'h80;
                    3'h5:ldob=8'hf7;
                    3'h6:ldob=8'hf7;
                    3'h7:ldob=8'hff;
                endcase
            end
        2'b10:
            begin
                case(count[14:12])//下
                    3'h0:ldob=8'hff;
                    3'h1:ldob=8'h80;
                    3'h2:ldob=8'hf7;
                    3'h3:ldob=8'he7;
                    3'h4:ldob=8'hd7;
                    3'h5:ldob=8'hf7;
                    3'h6:ldob=8'hf7;
                    3'h7:ldob=8'hf7;
                endcase
            end
        2'b11:
            begin
                case(count[14:12])//大
                    3'h0:ldob=8'hf7;
                    3'h1:ldob=8'hf7;
                    3'h2:ldob=8'h80;
                    3'h3:ldob=8'hf7;
                    3'h4:ldob=8'hf7;
                    3'h5:ldob=8'heb;
                    3'h6:ldob=8'hdd;
                    3'h7:ldob=8'hbe;
                endcase
            end
        endcase
    end

endmodule</code></pre><h1>蜂鸣器播放'梁祝’音乐模块</h1><pre><code class="lang-verilog">module music(clk_24MHz,buzzout,high,med,low);
input clk_24MHz;    

output buzzout;    
output[2:0] high,med,low;
reg[2:0] high,med,low;
reg buzzout_reg;
reg[24:0] count1,count2;    
reg[20:0] count_end;    
reg[7:0] counter;
reg clk_4Hz;

always@(posedge clk_24MHz)  
    begin
      if(count1&lt;25'd3000000)
        begin
          count1=count1+1; 
        end
      else
        begin
          count1=0;
          clk_4Hz=~clk_4Hz;
        end
    end

always@(posedge clk_24MHz)
    begin
        count2=count2+1;
        if(count2==count_end)
            begin
                count2=25'h0;
                buzzout_reg=!buzzout_reg;
            end
    end

always@(posedge clk_4Hz)
    begin
        case({high,med,low})
            9'b000000001:count_end=16'hbb9a;    
            9'b000000010:count_end=16'ha72f;    
            9'b000000011:count_end=16'h94f2;    
            9'b000000100:count_end=16'h8e78;    
            9'b000000101:count_end=16'h7d63;    
            9'b000000110:count_end=16'h6fb5;    
            9'b000000111:count_end=16'h637f;    
            9'b000001000:count_end=16'h5dfb;    
            9'b000010000:count_end=16'h53bb;    
            9'b000011000:count_end=16'h4a95;    
            9'b000100000:count_end=16'h4651;    
            9'b000101000:count_end=16'h3eb1;    
            9'b000110000:count_end=16'h37da;    
            9'b000111000:count_end=16'h31bf;    
            9'b001000000:count_end=16'h2ef2;    
            9'b010000000:count_end=16'h29d4;    
            9'b011000000:count_end=16'h2543;    
            9'b100000000:count_end=16'h232f;    
            9'b101000000:count_end=16'h1f58;    
            9'b110000000:count_end=16'h1bed;
            9'b111000000:count_end=16'h18df;
            default:count_end=16'hffff;    
        endcase
    end

always@(posedge clk_4Hz)
    begin
        if(counter==47) counter=0;
        else counter=counter+1;
        case(counter)
            0:{high,med,low}=9'b000000011;    
            1:{high,med,low}=9'b000000011;    
            2:{high,med,low}=9'b000000011;
            3:{high,med,low}=9'b000000011;
            4:{high,med,low}=9'b000000101;    
            5:{high,med,low}=9'b000000101;
            6:{high,med,low}=9'b000000101;
            7:{high,med,low}=9'b000000110;    
            8:{high,med,low}=9'b000001000; 
            9:{high,med,low}=9'b000001000;
            10:{high,med,low}=9'b000001000;
            11:{high,med,low}=9'b000010000;    
            12:{high,med,low}=9'b000000110;    
            13:{high,med,low}=9'b000001000; 
            14:{high,med,low}=9'b000000101;
            15:{high,med,low}=9'b000000101;    
            16:{high,med,low}=9'b000101000; 
            17:{high,med,low}=9'b000101000;
            18:{high,med,low}=9'b000101000;
            19:{high,med,low}=9'b001000000;
            20:{high,med,low}=9'b000110000; 
            21:{high,med,low}=9'b000101000;
            22:{high,med,low}=9'b000011000;
            23:{high,med,low}=9'b000101000; 
            24:{high,med,low}=9'b000010000;
            25:{high,med,low}=9'b000010000;
            26:{high,med,low}=9'b000010000;
            27:{high,med,low}=9'b000010000;
            28:{high,med,low}=9'b000010000;
            29:{high,med,low}=9'b000010000;
            30:{high,med,low}=9'b000010000;
            31:{high,med,low}=9'b000010000;
            32:{high,med,low}=9'b000010000;        
            33:{high,med,low}=9'b000010000;
            34:{high,med,low}=9'b000010000;
            35:{high,med,low}=9'b000011000;
            36:{high,med,low}=9'b000000111;
            37:{high,med,low}=9'b000000111;
            38:{high,med,low}=9'b000000110;
            39:{high,med,low}=9'b000000110;
            40:{high,med,low}=9'b000000101;
            41:{high,med,low}=9'b000000101;
            42:{high,med,low}=9'b000000101;
            43:{high,med,low}=9'b000000110; 
            44:{high,med,low}=9'b000001000;
            45:{high,med,low}=9'b000001000;
            46:{high,med,low}=9'b000010000; 
            47:{high,med,low}=9'b000010000;
        endcase
    end
assign buzzout=buzzout_reg;

endmodule</code></pre>
]]></content:encoded>
<slash:comments>0</slash:comments>
<comments>https://blog.x-tools.top/archives/34/#comments</comments>
<wfw:commentRss>https://blog.x-tools.top/feed/tag/%E5%B5%8C%E5%85%A5%E5%BC%8F/</wfw:commentRss>
</item>
<item>
<title>FPGA - 模块集合</title>
<link>https://blog.x-tools.top/archives/26/</link>
<guid>https://blog.x-tools.top/archives/26/</guid>
<pubDate>Fri, 03 Jun 2022 02:35:00 +0000</pubDate>
<dc:creator>小夏</dc:creator>
<description><![CDATA[&lt;!-- [toc] --&gt;本文使用的芯片是“EPM1270T144C5”因为博客框架的问题，代码显示可能会出现成堆的问题，请刷新此网页即可！分频模块0.5秒 count = 600...]]></description>
<content:encoded xml:lang="zh-CN"><![CDATA[
<p>&lt;!-- [toc] --&gt;</p><blockquote>本文使用的芯片是“EPM1270T144C5”<br>因为博客框架的问题，代码显示可能会出现成堆的问题，请刷新此网页即可！</blockquote><h1>分频模块</h1><blockquote>0.5秒 count = 6000000</blockquote><pre><code class="lang-verilog">module divclk(clkin,clkout);
    input clkin;
    output clkout;
    reg clkout;
    reg[25:0] count;
    always@(posedge clkin)
    begin
       count=count+1;
       if(count==6000000) //0.5s周期
       begin
         clkout=~clkout;
         count=0;
      end
    end
endmodule</code></pre><h1>Flag计数</h1><pre><code class="lang-verilog">module flagcount(clkin,flagout);
    input clkin;
    output[3:0] flagout;
    reg[3:0] flagout;
    always@(posedge clkin)
    begin
        flagout = flagout+1;
    end
endmodule</code></pre><h1>四个数码管显示相同数</h1><pre><code class="lang-verilog">module seg4(flagin,seg,sl);
    input[3:0] flagin;
    output[7:0] seg;
    output[3:0] sl;
    reg[7:0] seg;
    reg[3:0] sl;
    
    always
        sl=4'b0000;
        
    always@(flagin)
    begin
        case(flagin)
            4'h0:seg=8'hc0;//0
            4'h1:seg=8'hf9;//1
            4'h2:seg=8'ha4;//2
            4'h3:seg=8'hb0;//3
            4'h4:seg=8'h99;//4
            4'h5:seg=8'h92;//5
            4'h6:seg=8'h82;//6
            4'h7:seg=8'hf8;//7
            4'h8:seg=8'h80;//8
            4'h9:seg=8'h90;//8
            4'ha:seg=8'h88;//a
            4'hb:seg=8'h83;//b
            4'hc:seg=8'hc6;//c
            4'hd:seg=8'ha1;//d
            4'he:seg=8'h86;//e
            4'hf:seg=8'h8e;//f
        endcase
    end
endmodule</code></pre><h1>四位数码管分别显示</h1><pre><code class="lang-verilog">/*
 * 四位数码管显示三位不同数字
 * clk进24M
 */
module seg4Show3(clk,datain,slout,segout);
    input clk;
    input[9:0] datain;
    output[3:0] slout;
    output[7:0] segout;

    reg[3:0] disp_dat;
    reg[3:0] sl_reg;
    reg[7:0] seg_reg;
    reg[36:0] count;

    always@(posedge clk)
        count = count + 1;
    
    always@(count[14:13])
    begin
        case(count[14:13])
            2'h0:begin
                disp_dat = 4'b0001;
                sl_reg = 4'b1111;
            end
            2'h1:begin
                disp_dat = datain/100;
                sl_reg = 4'b1101;
            end
            2'h2:begin
                disp_dat = (datain%100)/10;
                sl_reg = 4'b1011;
            end
            2'h3:begin
                disp_dat = datain%10;
                sl_reg = 4'b0111;
            end
        endcase
    end
    
    always@(disp_dat)
    begin
        case(disp_dat)
            4'h0:seg_reg=8'hc0;//0
            4'h1:seg_reg=8'hf9;//1
            4'h2:seg_reg=8'ha4;//2
            4'h3:seg_reg=8'hb0;//3
            4'h4:seg_reg=8'h99;//4
            4'h5:seg_reg=8'h92;//5
            4'h6:seg_reg=8'h82;//6
            4'h7:seg_reg=8'hf8;//7
            4'h8:seg_reg=8'h80;//8
            4'h9:seg_reg=8'h90;//8
            4'ha:seg_reg=8'h88;//a
            4'hb:seg_reg=8'h83;//b
            4'hc:seg_reg=8'hc6;//c
            4'hd:seg_reg=8'ha1;//d
            4'he:seg_reg=8'h86;//e
            4'hf:seg_reg=8'h8e;//f
        endcase
    end
    assign segout = seg_reg;
    assign slout = sl_reg;

endmodule</code></pre><h1>按键防抖并且计数</h1><pre><code class="lang-verilog">/*
 *clkin 分频处理后的信号
 *keyin 按键按下的信号标志
 *out 输出的计数标志
 */
module count(clkin,keyin,out);
    input clkin;
    input keyin;
    output[9:0] out;
    reg[9:0] out;
    reg keyout;
    
    always@(posedge clkin)
        keyout=keyin;

    always@(negedge keyout)
    begin
       out=out+1;
       if(out==1000)
       begin
         out=0;
      end
    end
endmodule</code></pre><h1>1位Seg数码管 显示百位数字</h1><pre><code class="lang-verilog">/* 共阴数码管
 */
module display(datain,flagin,segout);
    input[9:0] datain;
    input[1:0] flagin;
    output[7:0] segout;
    reg[7:0] segout;

    always@(datain)
    begin
       case(flagin)
            2'd0:
           case(datain/100)
                0:segout=8'h3f;//0
                1:segout=8'h06;//1
                2:segout=8'h5b;//2
                3:segout=8'h4f;//3
                4:segout=8'h66;//4
                5:segout=8'h6d;//5
                6:segout=8'h7d;//6
                7:segout=8'h07;//7
                8:segout=8'h7f;//8
                9:segout=8'h6f;//9
                default:segout=8'h0;
            endcase
          2'd1:
           case((datain/10)%10)
                0:segout=8'h3f|8'h80;//0
                1:segout=8'h06|8'h80;//1
                2:segout=8'h5b|8'h80;//2
                3:segout=8'h4f|8'h80;//3
                4:segout=8'h66|8'h80;//4
                5:segout=8'h6d|8'h80;//5
                6:segout=8'h7d|8'h80;//6
                7:segout=8'h07|8'h80;//7
                8:segout=8'h7f|8'h80;//8
                9:segout=8'h6f|8'h80;//9
                default:segout=8'h0;
           endcase
         2'd2:
           case(datain%10)
                0:segout=8'h3f;//0
                1:segout=8'h06;//1
                2:segout=8'h5b;//2
                3:segout=8'h4f;//3
                4:segout=8'h66;//4
                5:segout=8'h6d;//5
                6:segout=8'h7d;//6
                7:segout=8'h07;//7
                8:segout=8'h7f;//8
                9:segout=8'h6f;//9
                default:segout=8'h0;
           endcase
        endcase
    end
endmodule
</code></pre><h1>8*8点阵显示汉字</h1><pre><code class="lang-verilog">/* 点阵显示 4个汉字 '上''下''中''大0'
 * clkinshow：进24M时钟信号，用于刷新上电
 * flagin：进显示汉字间隔，处理过的计数标志
 * ldoa,ldob：出点阵的位码输出口、数据输出口
 *
 * Tip：里面的count[14:12]，是刷新上电的间隔，应该非常小，可自行设置
 * case(flagin)下面分支可以改成自己的汉字编码
 */
module Showmatrix(clkinshow,flagin,ldoa,ldob);
    output[7:0] ldoa,ldob;
    input[1:0] flagin;
    input clkinshow;
    
    reg[7:0] ldoa,ldob;
    reg[32:0] count;
    
    always@(posedge clkinshow)
        count = count+1;
    
    always@(count[14:12])
    begin
    case(count[14:12])//上电
            3'h0:ldoa=8'hfe;
            3'h1:ldoa=8'hfd;
            3'h2:ldoa=8'hfb;
            3'h3:ldoa=8'hf7;
            3'h4:ldoa=8'hef;
            3'h5:ldoa=8'hdf;
            3'h6:ldoa=8'hbf;
            3'h7:ldoa=8'h7f;
        endcase
    end
    
    always@(count[14:12])
    begin
        case(flagin)
        2'b00:
            begin
                case(count[14:12])//上
                    3'h0:ldob=8'hf7;
                    3'h1:ldob=8'hf7;
                    3'h2:ldob=8'hc7;
                    3'h3:ldob=8'hf7;
                    3'h4:ldob=8'hf7;
                    3'h5:ldob=8'hf7;
                    3'h6:ldob=8'h80;
                    3'h7:ldob=8'hff;
                endcase
            end
        2'b01:
            begin
                case(count[14:12])//中
                    3'h0:ldob=8'hf7;
                    3'h1:ldob=8'hf7;
                    3'h2:ldob=8'h80;
                    3'h3:ldob=8'hb6;
                    3'h4:ldob=8'h80;
                    3'h5:ldob=8'hf7;
                    3'h6:ldob=8'hf7;
                    3'h7:ldob=8'hff;
                endcase
            end
        2'b10:
            begin
                case(count[14:12])//下
                    3'h0:ldob=8'hff;
                    3'h1:ldob=8'h80;
                    3'h2:ldob=8'hf7;
                    3'h3:ldob=8'he7;
                    3'h4:ldob=8'hd7;
                    3'h5:ldob=8'hf7;
                    3'h6:ldob=8'hf7;
                    3'h7:ldob=8'hf7;
                endcase
            end
        2'b11:
            begin
                case(count[14:12])//大
                    3'h0:ldob=8'hf7;
                    3'h1:ldob=8'hf7;
                    3'h2:ldob=8'h80;
                    3'h3:ldob=8'hf7;
                    3'h4:ldob=8'hf7;
                    3'h5:ldob=8'heb;
                    3'h6:ldob=8'hdd;
                    3'h7:ldob=8'hbe;
                endcase
            end
        endcase
    end

endmodule</code></pre>
]]></content:encoded>
<slash:comments>0</slash:comments>
<comments>https://blog.x-tools.top/archives/26/#comments</comments>
<wfw:commentRss>https://blog.x-tools.top/feed/tag/%E5%B5%8C%E5%85%A5%E5%BC%8F/</wfw:commentRss>
</item>
</channel>
</rss>