KT25-0812_82A-UART/README.html
2025-08-21 16:15:01 +08:00

704 lines
14 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html>
<head>
<title>README.md</title>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<style>
/* https://github.com/microsoft/vscode/blob/master/extensions/markdown-language-features/media/markdown.css */
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
body {
font-family: var(--vscode-markdown-font-family, -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "Ubuntu", "Droid Sans", sans-serif);
font-size: var(--vscode-markdown-font-size, 14px);
padding: 0 26px;
line-height: var(--vscode-markdown-line-height, 22px);
word-wrap: break-word;
}
#code-csp-warning {
position: fixed;
top: 0;
right: 0;
color: white;
margin: 16px;
text-align: center;
font-size: 12px;
font-family: sans-serif;
background-color:#444444;
cursor: pointer;
padding: 6px;
box-shadow: 1px 1px 1px rgba(0,0,0,.25);
}
#code-csp-warning:hover {
text-decoration: none;
background-color:#007acc;
box-shadow: 2px 2px 2px rgba(0,0,0,.25);
}
body.scrollBeyondLastLine {
margin-bottom: calc(100vh - 22px);
}
body.showEditorSelection .code-line {
position: relative;
}
body.showEditorSelection .code-active-line:before,
body.showEditorSelection .code-line:hover:before {
content: "";
display: block;
position: absolute;
top: 0;
left: -12px;
height: 100%;
}
body.showEditorSelection li.code-active-line:before,
body.showEditorSelection li.code-line:hover:before {
left: -30px;
}
.vscode-light.showEditorSelection .code-active-line:before {
border-left: 3px solid rgba(0, 0, 0, 0.15);
}
.vscode-light.showEditorSelection .code-line:hover:before {
border-left: 3px solid rgba(0, 0, 0, 0.40);
}
.vscode-light.showEditorSelection .code-line .code-line:hover:before {
border-left: none;
}
.vscode-dark.showEditorSelection .code-active-line:before {
border-left: 3px solid rgba(255, 255, 255, 0.4);
}
.vscode-dark.showEditorSelection .code-line:hover:before {
border-left: 3px solid rgba(255, 255, 255, 0.60);
}
.vscode-dark.showEditorSelection .code-line .code-line:hover:before {
border-left: none;
}
.vscode-high-contrast.showEditorSelection .code-active-line:before {
border-left: 3px solid rgba(255, 160, 0, 0.7);
}
.vscode-high-contrast.showEditorSelection .code-line:hover:before {
border-left: 3px solid rgba(255, 160, 0, 1);
}
.vscode-high-contrast.showEditorSelection .code-line .code-line:hover:before {
border-left: none;
}
img {
max-width: 100%;
max-height: 100%;
}
a {
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
a:focus,
input:focus,
select:focus,
textarea:focus {
outline: 1px solid -webkit-focus-ring-color;
outline-offset: -1px;
}
hr {
border: 0;
height: 2px;
border-bottom: 2px solid;
}
h1 {
padding-bottom: 0.3em;
line-height: 1.2;
border-bottom-width: 1px;
border-bottom-style: solid;
}
h1, h2, h3 {
font-weight: normal;
}
table {
border-collapse: collapse;
}
table > thead > tr > th {
text-align: left;
border-bottom: 1px solid;
}
table > thead > tr > th,
table > thead > tr > td,
table > tbody > tr > th,
table > tbody > tr > td {
padding: 5px 10px;
}
table > tbody > tr + tr > td {
border-top: 1px solid;
}
blockquote {
margin: 0 7px 0 5px;
padding: 0 16px 0 10px;
border-left-width: 5px;
border-left-style: solid;
}
code {
font-family: Menlo, Monaco, Consolas, "Droid Sans Mono", "Courier New", monospace, "Droid Sans Fallback";
font-size: 1em;
line-height: 1.357em;
}
body.wordWrap pre {
white-space: pre-wrap;
}
pre:not(.hljs),
pre.hljs code > div {
padding: 16px;
border-radius: 3px;
overflow: auto;
}
pre code {
color: var(--vscode-editor-foreground);
tab-size: 4;
}
/** Theming */
.vscode-light pre {
background-color: rgba(220, 220, 220, 0.4);
}
.vscode-dark pre {
background-color: rgba(10, 10, 10, 0.4);
}
.vscode-high-contrast pre {
background-color: rgb(0, 0, 0);
}
.vscode-high-contrast h1 {
border-color: rgb(0, 0, 0);
}
.vscode-light table > thead > tr > th {
border-color: rgba(0, 0, 0, 0.69);
}
.vscode-dark table > thead > tr > th {
border-color: rgba(255, 255, 255, 0.69);
}
.vscode-light h1,
.vscode-light hr,
.vscode-light table > tbody > tr + tr > td {
border-color: rgba(0, 0, 0, 0.18);
}
.vscode-dark h1,
.vscode-dark hr,
.vscode-dark table > tbody > tr + tr > td {
border-color: rgba(255, 255, 255, 0.18);
}
</style>
<style>
/* Tomorrow Theme */
/* http://jmblog.github.com/color-themes-for-google-code-highlightjs */
/* Original theme - https://github.com/chriskempson/tomorrow-theme */
/* Tomorrow Comment */
.hljs-comment,
.hljs-quote {
color: #8e908c;
}
/* Tomorrow Red */
.hljs-variable,
.hljs-template-variable,
.hljs-tag,
.hljs-name,
.hljs-selector-id,
.hljs-selector-class,
.hljs-regexp,
.hljs-deletion {
color: #c82829;
}
/* Tomorrow Orange */
.hljs-number,
.hljs-built_in,
.hljs-builtin-name,
.hljs-literal,
.hljs-type,
.hljs-params,
.hljs-meta,
.hljs-link {
color: #f5871f;
}
/* Tomorrow Yellow */
.hljs-attribute {
color: #eab700;
}
/* Tomorrow Green */
.hljs-string,
.hljs-symbol,
.hljs-bullet,
.hljs-addition {
color: #718c00;
}
/* Tomorrow Blue */
.hljs-title,
.hljs-section {
color: #4271ae;
}
/* Tomorrow Purple */
.hljs-keyword,
.hljs-selector-tag {
color: #8959a8;
}
.hljs {
display: block;
overflow-x: auto;
color: #4d4d4c;
padding: 0.5em;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}
</style>
<style>
/*
* Markdown PDF CSS
*/
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "Ubuntu", "Droid Sans", sans-serif, "Meiryo";
padding: 0 12px;
}
pre {
background-color: #f8f8f8;
border: 1px solid #cccccc;
border-radius: 3px;
overflow-x: auto;
white-space: pre-wrap;
overflow-wrap: break-word;
}
pre:not(.hljs) {
padding: 23px;
line-height: 19px;
}
blockquote {
background: rgba(127, 127, 127, 0.1);
border-color: rgba(0, 122, 204, 0.5);
}
.emoji {
height: 1.4em;
}
code {
font-size: 14px;
line-height: 19px;
}
/* for inline code */
:not(pre):not(.hljs) > code {
color: #C9AE75; /* Change the old color so it seems less like an error */
font-size: inherit;
}
/* Page Break : use <div class="page"/> to insert page break
-------------------------------------------------------- */
.page {
page-break-after: always;
}
</style>
<script src="https://unpkg.com/mermaid/dist/mermaid.min.js"></script>
</head>
<body>
<script>
mermaid.initialize({
startOnLoad: true,
theme: document.body.classList.contains('vscode-dark') || document.body.classList.contains('vscode-high-contrast')
? 'dark'
: 'default'
});
</script>
<h1 id="%E5%BC%95%E8%84%9A%E6%8E%92%E5%88%97">引脚排列</h1>
<p><img src="./pin" alt="引脚定义"></p>
<h2 id="uart-%E9%80%9A%E8%AE%AF%E5%8D%8F%E8%AE%AE-115200-n-8-1">UART 通讯协议 115200 N 8 1</h2>
<ul>
<li>发送
<table>
<thead>
<tr>
<th>head</th>
<th>length</th>
<th>CMD</th>
<th>DATA</th>
<th>XOR</th>
<th>tail</th>
</tr>
</thead>
<tbody>
<tr>
<td>02</td>
<td>04</td>
<td>A0</td>
<td>01</td>
<td>FF</td>
<td>03</td>
</tr>
</tbody>
</table>
</li>
<li>回复
<table>
<thead>
<tr>
<th>head</th>
<th>length</th>
<th>CMD</th>
<th>ERR</th>
<th>XOR</th>
<th>tail</th>
</tr>
</thead>
<tbody>
<tr>
<td>02</td>
<td>04</td>
<td>A0</td>
<td>00</td>
<td>FF</td>
<td>03</td>
</tr>
</tbody>
</table>
</li>
<li>解释:
<ul>
<li>heat帧头 一个字节 0x02</li>
<li>tail帧尾 一个字节 0x03</li>
<li>length长度 一个字节 从长度到校验的长度,包含长度和校验</li>
<li>CMD命令字 一个字节</li>
<li>DATA数据区不定长</li>
<li>XOR校验一个字节的xor校验,调试可以填写一个字节FF当此字节为FF时为不校验</li>
</ul>
</li>
<li>指令列表:
<ul>
<li>0xA0 播放</li>
<li>0xA1 暂停</li>
<li>0xA2 播放/暂停</li>
<li>0xA3 下一曲</li>
<li>0xA4 上一曲</li>
<li>0xA5 停止</li>
<li>0xA6 音量加</li>
<li>0xA7 音量减</li>
<li>0xA8 设置音量</li>
<li>0xA9 静音</li>
<li>0xAA 解除静音</li>
<li>0xAB 播放指定曲目(通配符)</li>
<li>0xAC 播放指定曲目(带扩展名)</li>
<li>0xAD 播放指定曲目(数字)</li>
</ul>
</li>
</ul>
<h2 id="%E6%8C%87%E4%BB%A4%E8%AF%A6%E8%BF%B0">指令详述</h2>
<ul>
<li>系统复位0xA0/A1/A2/A3/A4/A5/A6/A7/A9/AA
<table>
<thead>
<tr>
<th>HEAD</th>
<th>LENGTH</th>
<th>CMD</th>
<th>CHK</th>
<th>TAIL</th>
</tr>
</thead>
<tbody>
<tr>
<td>0x02</td>
<td>1Byte</td>
<td>0xA0</td>
<td>1Byte</td>
<td>0x03</td>
</tr>
</tbody>
</table>
</li>
<li>播放/暂停0xC2
<table>
<thead>
<tr>
<th>HEAD</th>
<th>LENGTH</th>
<th>CMD</th>
<th>CHK</th>
<th>TAIL</th>
</tr>
</thead>
<tbody>
<tr>
<td>0x02</td>
<td>1Byte</td>
<td>0xC2</td>
<td>1Byte</td>
<td>0x03</td>
</tr>
</tbody>
</table>
</li>
<li>设置音量0xA8
<table>
<thead>
<tr>
<th>HEAD</th>
<th>LENGTH</th>
<th>CMD</th>
<th>VOLUME</th>
<th>CHK</th>
<th>TAIL</th>
</tr>
</thead>
<tbody>
<tr>
<td>0x02</td>
<td>1Byte</td>
<td>0xA8</td>
<td>0-30</td>
<td>1Byte</td>
<td>0x03</td>
</tr>
</tbody>
</table>
<ul>
<li>VOLUME 0-30</li>
</ul>
</li>
<li>播放指定曲目(通配符)AB
<table>
<thead>
<tr>
<th>HEAD</th>
<th>LENGTH</th>
<th>CMD</th>
<th>STA</th>
<th>NAME</th>
<th>END</th>
<th>CHK</th>
<th>TAIL</th>
</tr>
</thead>
<tbody>
<tr>
<td>0x02</td>
<td>1Byte</td>
<td>0xAB</td>
<td>'$'</td>
<td>'abc'</td>
<td>'$'</td>
<td>1Byte</td>
<td>0x03</td>
</tr>
</tbody>
</table>
<ul>
<li>STA :名字起始,字符'$'(0x24)。</li>
<li>END : 名字结束,字符'$'(0x24)。</li>
<li>NAME :名字字符串,支持通配符,注:会自动增加扩展名实例为3字节abc61 62 63,<code>实际上是播放 &quot;abc.*&quot;, 程序自动增加 &quot;.*&quot; 通配符扩展名,&quot;ab*&quot;也是合法的,会播放&quot;ab*.*&quot;</code></li>
<li>文件必须存在否则播放失败</li>
</ul>
</li>
<li>播放指定曲目(全路径)AC
<table>
<thead>
<tr>
<th>HEAD</th>
<th>LENGTH</th>
<th>CMD</th>
<th>STA</th>
<th>NAME</th>
<th>END</th>
<th>CHK</th>
<th>TAIL</th>
</tr>
</thead>
<tbody>
<tr>
<td>0x02</td>
<td>1Byte</td>
<td>0xAC</td>
<td>'$'</td>
<td>'abc.mp3'</td>
<td>'$'</td>
<td>1Byte</td>
<td>0x03</td>
</tr>
</tbody>
</table>
<ul>
<li>STA :名字起始,字符'$'(0x24)。</li>
<li>END : 名字结束,字符'$'(0x24)。</li>
<li>NAME :名字字符串,必须写全文件名例如文件名采用8+3格式只识别文件名的前2个字符例如01.mp3和010.mp3是不同的</li>
<li>文件必须存在否则播放失败</li>
</ul>
</li>
<li>播放指定曲目(文件号)AD
<table>
<thead>
<tr>
<th>HEAD</th>
<th>LENGTH</th>
<th>CMD</th>
<th>FH</th>
<th>FL</th>
<th>CHK</th>
<th>TAIL</th>
</tr>
</thead>
<tbody>
<tr>
<td>0x02</td>
<td>1Byte</td>
<td>0xAD</td>
<td>1Byte</td>
<td>1Byte</td>
<td>1Byte</td>
<td>0x03</td>
</tr>
</tbody>
</table>
<ul>
<li>FHFL组合成以恶搞16bit的整形例如 FH=0x00 FL=0x02 实际上是播放0x0002曲目曲目的顺序号是拷贝进磁盘的顺序</li>
<li>文件必须存在否则播放失败</li>
</ul>
</li>
<li>指定文件号播放0xC8
<table>
<thead>
<tr>
<th>HEAD</th>
<th>LENGTH</th>
<th>CMD</th>
<th>NUM</th>
<th>LOOP</th>
<th>CHK</th>
<th>TAIL</th>
</tr>
</thead>
<tbody>
<tr>
<td>0x02</td>
<td>1Byte</td>
<td>0xC8</td>
<td>1-99</td>
<td>1Byte</td>
<td>1Byte</td>
<td>0x03</td>
</tr>
</tbody>
</table>
<ul>
<li>NUM 文件名号码。注文件名采用8+3格式只识别文件名的前2个字符例如01.mp3和01月光小夜曲.mp3是相同的月光小夜曲可有可无但前面序号必须有存放文件时需注意。</li>
<li>LOOP 循环次数0为单曲无限循环</li>
<li>文件必须存在否则播放失败</li>
</ul>
</li>
</ul>
<h2 id="%E9%99%84%E5%BD%951%E6%A0%A1%E9%AA%8C">附录1校验</h2>
<ul>
<li>校验方式为校验和计算方式为数据累计和取反加1的方式</li>
<li>举例发送系统复位指令A00x02 0x02 0xA0 CheckSum 0x03
<ul>
<li>其中头尾分别为02 03</li>
<li>计算第二个02 + 指令A0相加结果取反再+1得到CheckSum</li>
<li>校验:数据段+校验后的值为0</li>
<li>详细算法<pre class="hljs"><code><div> <span class="hljs-keyword">uint8_t</span> buf[<span class="hljs-number">16</span>];
<span class="hljs-keyword">int</span> index = <span class="hljs-number">0</span>;
buf[index++] = <span class="hljs-number">0x02</span>; <span class="hljs-comment">//头</span>
buf[index++] = <span class="hljs-number">0x00</span>; <span class="hljs-comment">//长度临时赋值0</span>
buf[index++] = <span class="hljs-number">0xA0</span>; <span class="hljs-comment">//指令</span>
buf[<span class="hljs-number">1</span>] = index - <span class="hljs-number">1</span>; <span class="hljs-comment">//数据填充完成后,重新赋值长度(0x02)</span>
<span class="hljs-keyword">uint16_t</span> sum = <span class="hljs-number">0</span>;
<span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i &lt; index - <span class="hljs-number">1</span>; i++)
{
sum += buf[<span class="hljs-number">1</span>+i]; <span class="hljs-comment">//从第一个字节开始累加,去除头,</span>
}
<span class="hljs-comment">//此时累加完成sum0x02 + 0xA0 = 0xA2</span>
sum = ~sum + <span class="hljs-number">1</span>; <span class="hljs-comment">//取反加1</span>
<span class="hljs-comment">//sum = 0xff5D + 1 = 0xff5E</span>
buf[index++] = (u8)sum; <span class="hljs-comment">//强制转换成uint8_t类型,截断后为 0x5E</span>
buf[index++] = <span class="hljs-number">0x03</span>; <span class="hljs-comment">//尾</span>
<span class="hljs-comment">//此时buf = {0x02,0x02,0xA0,0x5E,0x03}</span>
<span class="hljs-comment">//下面校验</span>
<span class="hljs-comment">//0x02 + 0xA0 + 0x5E = 0x0100</span>
<span class="hljs-comment">//将0x100强转为uint8_t后截断后 = 0校验通过</span>
</div></code></pre>
</li>
</ul>
</li>
</ul>
<h2 id="%E9%99%84%E5%BD%952-errcode-%E9%94%99%E8%AF%AF%E5%AE%9A%E4%B9%89">附录2 ERRCODE 错误定义:</h2>
<pre><code>- 0指令正确数据正确且执行正确
- 1一个通用的错误可能是一个未定义的错误
- 2未识别的指令
- 3参数错误
- 4帧错误此包数据未找到帧头或者未找到帧尾
- 5长度错误
- 6校验错误</code></pre>
</body>
</html>