KT25-0812_82A-UART/README.html

704 lines
14 KiB
HTML
Raw Normal View History

2025-08-21 08:15:01 +00:00
<!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>