帮用STC8H8K64U写个流水灯的演示程序
帮用STC8H8K64U写个流水灯的演示程序<p>好的!下面我基于 <strong>STC8H8K64U</strong> 的数据手册和官方实验指导书,为你写一个完整的流水灯演示程序。</p>
<hr />
<h2>📌 硬件说明</h2>
<p>根据 STC8H8K64U 实验箱/开天斧的典型原理图:</p>
<ul>
<li><strong>LED 指示灯</strong>接在 <strong>P6 口</strong>(P6.0~P6.7),<strong>低电平点亮</strong></li>
<li><strong>P4.0</strong> 控制 PNP 三极管作为 LED 总电源开关,<strong>P4.0 输出 0 时总电源导通</strong></li>
<li>如果使用自己的最小系统板,请根据实际硬件调整端口</li>
</ul>
<hr />
<h2>📝 完整代码(使用定时器中断实现流水灯)</h2>
<pre><code class="language-c">/****************************************************************
* 文件名: main.c
* 功能: STC8H8K64U 流水灯演示程序
* 使用定时器0 1ms中断,每500ms切换一次流水灯
* 8个LED接P6口(低电平点亮),P4.0为总电源控制(低电平导通)
* 晶振: 使用内部IRC,建议设置为 11.0592MHz 或 24MHz
****************************************************************/
#include "stc8h.h" // STC8H头文件
#define LED_PORT P6 // LED接P6口
#define LED_PIN_ALL0xFF // 8位全亮/全灭值
// 流水灯方向定义
#define LEFT_TO_RIGHT0
#define RIGHT_TO_LEFT1
// 全局变量
bitdir = LEFT_TO_RIGHT; // 流水灯方向
u8 led_index = 0; // 当前点亮的LED索引(0~7)
u16timer_count = 0; // 定时器计数
/******************** 毫秒级延时函数(查询方式) *******************/
void delay_ms(u16 ms)
{
u16 i;
for(i = 0; i < ms; i++)
{
// 12MHz下约延时1ms (根据实际主频可微调)
u16 j = 12000 / 12;
while(j--);
}
}
/******************** I/O口初始化 *******************/
void GPIO_init(void)
{
// P6口设置为推挽输出模式(P6M1=0, P6M0=0xFF)
P6M1 = 0x00;
P6M0 = 0xFF;
// P4.0设置为推挽输出
P4M1 = 0x00;
P4M0 = 0x01;
// 初始状态:关闭总电源(P4.0=1),LED全部熄灭(P6=0xFF)
P4 |= 0x01; // P4.0 = 1,关断LED总电源
P6 = 0xFF; // 所有LED熄灭(低电平点亮)
}
/******************** 定时器0初始化 *******************/
// 使用定时器0,模式0(16位自动重装载)
// 时钟频率 = 主频 / 12
// 定时1ms示例:以12MHz主频为例
void Timer0_init(void)
{
// 注意:如果使用24MHz,需要相应调整重装值
// 此处以 12MHz 主频为例:定时1ms
// 计数脉冲 = 12MHz / 12 = 1MHz,计1000次 = 1ms
// 重装值 = 65536 - 1000 = 64536 = 0xFC18
AUXR |= 0x80; // 定时器0时钟1T模式(如果要用1T)
// 此处使用12T模式,更通用
AUXR &= ~0x80; // 定时器0时钟12T模式
TMOD &= 0xF0; // 清除定时器0模式位
TMOD |= 0x00; // 模式0(16位自动重装载)
// 以12MHz主频为例,12T模式,1ms定时
// 实际请根据你的主频用ISP软件中的"定时器计算器"工具自动生成
TL0 = 0x18; // 低字节
TH0 = 0xFC; // 高字节(65536-1000=64536=0xFC18)
ET0 = 1; // 使能定时器0中断
TR0 = 1; // 启动定时器0
}
/******************** 主函数 *******************/
void main(void)
{
P_SW2 |= 0x80; // 使能访问XFR扩展寄存器(很多新功能需要此设置)
GPIO_init(); // 初始化I/O口
Timer0_init(); // 初始化定时器0
EA= 1; // 开启总中断
// 开启LED总电源
P4 &= ~0x01; // P4.0 = 0,导通PNP三极管
// 主循环:流水灯由定时器中断驱动,主循环可执行其他任务
while(1)
{
// 此处可以放其他任务代码,流水灯由中断自动运行
// 例如:检测按键、串口通信等
}
}
/******************** 定时器0中断服务函数 *******************/
void Timer0_ISR(void) interrupt 1
{
// 每1ms进入一次中断
timer_count++;
// 每500ms切换一次流水灯位置
if(timer_count >= 500)
{
timer_count = 0;
// 根据方向更新索引
if(dir == LEFT_TO_RIGHT)
{
led_index++;
if(led_index >= 8)
{
led_index = 0;
}
}
else // RIGHT_TO_LEFT
{
if(led_index == 0)
{
led_index = 7;
}
else
{
led_index--;
}
}
// 更新LED显示:将对应位置0(点亮),其余置1(熄灭)
// 例: led_index=0 => 0xFE (点亮P6.0)
// led_index=1 => 0xFD (点亮P6.1)
// ...以此类推
LED_PORT = ~(1 << led_index);
}
}
</code></pre>
<hr />
<h2>💡 使用说明 & 重要提醒</h2>
<h3>1️⃣ 关于主频与定时器重装值</h3>
<p>上面的代码以 <strong>12MHz</strong> 主频为例写了定时初值。<strong>请根据你实际设置的主频</strong>,使用 <strong>STC-ISP(AIapp-ISP)下载软件</strong> 中的 <strong>"定时器计算器"</strong> 工具自动生成准确的定时器初值,更省心、更准确:</p>
<blockquote>
<p>ISP软件 → 定时器计算器 → 选择"定时器0" → 设置定时时间1ms → 自动生成代码</p>
</blockquote>
<h3>2️⃣ 如果你的LED不是接在P6口</h3>
<p>请修改 <code>GPIO_init()</code> 中的端口配置:</p>
<ul>
<li>改 <code>P6M0/P6M1</code> 为对应的 <code>PxM0/PxM1</code></li>
<li>改 <code>LED_PORT</code> 宏定义中的端口</li>
</ul>
<h3>3️⃣ 如果不需要P4.0总电源控制</h3>
<p>将 <code>GPIO_init()</code> 和 <code>main()</code> 中与 P4.0 相关的代码注释掉即可。</p>
<h3>4️⃣ 流水灯方向</h3>
<p>程序默认从左到右(P6.0 → P6.7),如需反转,将主循环里的 <code>dir</code> 变量改为 <code>RIGHT_TO_LEFT</code>。</p>
<h3>5️⃣ 不依赖定时器的极简版(软件延时)</h3>
<p>如果你不想用定时器,下面是一个最简单的软件延时流水灯版本:</p>
<pre><code class="language-c">#include "stc8h.h"
void delay_ms(u16 ms)
{
u16 i, j;
for(i = 0; i < ms; i++)
for(j = 0; j < 12000/12; j++);
}
void main(void)
{
u8 i;
P_SW2 |= 0x80;
// P6推挽输出,P4.0推挽输出
P6M0 = 0xFF;P6M1 = 0x00;
P4M0 = 0x01;P4M1 = 0x00;
P4 &= ~0x01; // P4.0=0,开启LED总电源
while(1)
{
for(i = 0; i < 8; i++)
{
P6 = ~(1 << i); // 逐位点亮
delay_ms(300); // 延时约300ms
}
}
}
</code></pre>
<hr />
<h2>📚 信息来源</h2>
<table>
<thead>
<tr>
<th>内容</th>
<th>来源</th>
</tr>
</thead>
<tbody>
<tr>
<td>I/O口模式配置(P6M0/P6M1)</td>
<td>STC8H数据手册<strong>第12章 配置I/O口</strong></td>
</tr>
<tr>
<td>实验箱LED硬件原理(P6口接LED,P4.0总电源)</td>
<td>STC8H实验指导书<strong>2.4~2.7 点灯实验</strong></td>
</tr>
<tr>
<td>定时器0配置</td>
<td>STC8H数据手册<strong>第16章 定时器/计数器</strong> —— 16.2.3/16.2.4</td>
</tr>
</tbody>
</table>
<blockquote>
<p>💬 如果在实际调试中遇到问题,欢迎继续提问!或者在 STC 官方论坛(<a href="http://www.stcaimcu.com">www.stcaimcu.com</a>)搜索更多示例。</p>
</blockquote>
<hr />
<p><a href="https://www.stcaimcu.com/plugin.php?id=twpx_xunsearch&mod=forum&q=%E5%B8%AE%E7%94%A8%20STC8H8K64U%E5%86%99%E4%B8%AA%E6%B5%81%E6%B0%B4%E7%81%AF%E7%9A%84%E6%BC%94%E7%A4%BA%E7%A8%8B%E5%BA%8F&f=_all&m=yes&syn=yes&s=relevance&fid=0">🔍 搜索 "帮用 STC8H8K64U写个流水灯的演示程序"</a></p>
<p><strong>📌 相关论坛讨论</strong></p>
<ol>
<li><a href="https://www.stcaimcu.com/forum.php?mod=viewthread&tid=257&highlight=%E5%B8%AE%E7%94%A8STC8H8K64U%E5%86%99%E4%B8%AA%E6%B5%81%E6%B0%B4%E7%81%AF%E7%9A%84%E6%BC%94%E7%A4%BA%E7%A8%8B%E5%BA%8F&page=1&extra=#pid972">8H8K64U 实验箱演示程序包中有 LCD12864, LCD1602的演示程序</a></li>
<li><a href="https://www.stcaimcu.com/forum.php?mod=viewthread&tid=17898&highlight=%E5%B8%AE%E7%94%A8STC8H8K64U%E5%86%99%E4%B8%AA%E6%B5%81%E6%B0%B4%E7%81%AF%E7%9A%84%E6%BC%94%E7%A4%BA%E7%A8%8B%E5%BA%8F&page=2&extra=#pid167035">请教关于 AiCube的I2C的两个问题 | 已解决,最新修改在5楼</a></li>
<li><a href="https://www.stcaimcu.com/forum.php?mod=viewthread&tid=2813&highlight=%E5%B8%AE%E7%94%A8STC8H8K64U%E5%86%99%E4%B8%AA%E6%B5%81%E6%B0%B4%E7%81%AF%E7%9A%84%E6%BC%94%E7%A4%BA%E7%A8%8B%E5%BA%8F&page=1&extra=#pid19346">从8051到32位8051,何宾教授带大家一起穿越</a></li>
</ol>
页:
[1]