標(biāo)題:
不借助工具,使用串口輸出對(duì)STC8A8K64S4A12的IRTRIM值進(jìn)行標(biāo)定
[打印本頁(yè)]
作者:
michaelchain
時(shí)間:
2021-11-11 19:03
標(biāo)題:
不借助工具,使用串口輸出對(duì)STC8A8K64S4A12的IRTRIM值進(jìn)行標(biāo)定
STC8A8K64S4A12這個(gè)型號(hào)的MCU, 因?yàn)闆]有固化的頻率調(diào)節(jié)值, 要么在STC-ISP燒錄時(shí)設(shè)置寫入, 要么通過idata高地址區(qū)讀取, 這對(duì)于Linux下的SDCC用戶就非常不方便, 既不能用STC-ISP, 寫入SDCC編譯后的程序也無法在idata區(qū)讀取對(duì)應(yīng)的值. 相比較STC8A8K64D4就方便許多, 在xdata區(qū)域有固定的值可以讀取.
那么對(duì)于Linux下的SDCC用戶, 如何去確定這個(gè)頻率調(diào)節(jié)值? 一個(gè)辦法是通過邏輯分析儀去標(biāo)定, 但是如果沒有邏輯分析儀呢? 還可以通過指定的串口波特率去標(biāo)定.
這種方式是因?yàn)榇诓ㄌ芈逝c系統(tǒng)時(shí)鐘是關(guān)聯(lián)的, 如果假定當(dāng)前系統(tǒng)時(shí)鐘頻率為X, 那么對(duì)應(yīng)一個(gè)確定的波特率, 例如9600, 對(duì)應(yīng)的寄存器值是固定的, 如果芯片按這個(gè)值運(yùn)行, 只有當(dāng)系統(tǒng)時(shí)鐘頻率與預(yù)設(shè)的值接近, 上位機(jī)才接收到正確的輸出, 其它情況看到的都是亂碼, 如果在代碼中不斷調(diào)節(jié)頻率, 同時(shí)輸出當(dāng)前頻率對(duì)應(yīng)的IRTRIM和LIRTRIM值, 根據(jù)亂碼和正常接收的情況, 就能判斷出對(duì)應(yīng)此頻率的IRTRIM和LIRTRIM值.
編譯這個(gè)程序后寫入STC8A8K64S4A12, 使用USB2TTL連接串口1, 波特率9600, 觀察輸出的字符串.
當(dāng)實(shí)際頻率接近預(yù)設(shè)的頻率時(shí), 能觀察到非亂碼的輸出. 取非亂碼區(qū)間的中間點(diǎn)對(duì)應(yīng)的值, 就可以作為此頻率對(duì)應(yīng)的IRTRIM和LIRTRIM值.
代碼已經(jīng)添加了對(duì)應(yīng)的宏處理, 可以兼容SDCC和Keil C51環(huán)境.
/*****************************************************************************/
/**
* \file itrim_detect.c
* \brief 使用固定波特率串口輸出標(biāo)定STC8A8K64S4A12各頻率的ITRIM
* \version v0.1
******************************************************************************/
/*****************************************************************************/
/**
* \brief 自適應(yīng)SDCC和Keil C51的宏處理
******************************************************************************/
#if defined (SDCC) || defined (__SDCC)
# define SBIT(name, addr, bit) __sbit __at(addr+bit) name
# define SFR(name, addr) __sfr __at(addr) name
# define SFRX(name, addr) __xdata volatile unsigned char __at(addr) name
#define NOP() __asm NOP __endasm
#elif defined __CX51__
# define SBIT(name, addr, bit) sbit name = addr^bit
# define SFR(name, addr) sfr name = addr
# define SFRX(name, addr) volatile unsigned char xdata name _at_ addr
extern void _nop_ (void);
#define NOP() _nop_()
/** default
* unrecognized compiler
*/
#else
# warning unrecognized compiler
# define SBIT(name, addr, bit) volatile bool name
# define SFR(name, addr) volatile unsigned char name
# define SFRX(name, addr) volatile unsigned char name
#endif
/*****************************************************************************/
/**
* \brief 代碼中涉及的寄存器
******************************************************************************/
SBIT(TI, 0x98, 1);
SFR(PCON, 0x87);
SFR(AUXR, 0x8E);
SFR(SCON, 0x98);
SFR(SBUF, 0x99);
SFR(LIRTRIM, 0x9E);
SFR(IRTRIM, 0x9F);
SFR(P_SW2, 0xBA);
SFR(T2H, 0xD6);
SFR(T2L, 0xD7);
SFRX(CLKDIV, 0xfe01);
SFRX(IRC24MCR, 0xfe02);
static const char hexTable[16] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
/*****************************************************************************/
/**
* \brief 時(shí)鐘和串口1初始化
******************************************************************************/
void clock_init()
{
// [ BAH,0,0x00]: 外設(shè)端口切換控制寄存器2,串口2/3/4,I2C,比較器
P_SW2 = 0x80;
// [FE01H,1,0x00]: 時(shí)鐘分頻寄存器,ISP可能寫入預(yù)設(shè)值
CLKDIV = 0x00;
// [ 9EH,0,0x00]: IRC頻率微調(diào)寄存器, ISP可能寫入預(yù)設(shè)值
LIRTRIM = 0x00;
// [ BAH,0,0x00]: 外設(shè)端口切換控制寄存器2,串口2/3/4,I2C,比較器
P_SW2 = 0x00;
// [ 87H,0,0x30]: 電源控制寄存器
PCON = 0xB0;
// [ 98H,0,0x00]: 串口1控制寄存器
SCON = 0x50;
// [ 8EH,0,0x01]: 輔助寄存器
AUXR = 0x15;
}
/*****************************************************************************/
/**
* \brief 不同頻率對(duì)應(yīng)的串口初始化程序
******************************************************************************/
void uart_init_18m_9600()
{
// [ D6H,0,0x00]: 定時(shí)器2高字節(jié)
T2H = 0xFE;
// [ D7H,0,0x00]: 定時(shí)器2低字節(jié)
T2L = 0x2B;
}
void uart_init_22m1184_9600()
{
// [ D6H,0,0x00]: 定時(shí)器2高字節(jié)
T2H = 0xFD;
// [ D7H,0,0x00]: 定時(shí)器2低字節(jié)
T2L = 0xC0;
}
void uart_init_24m_9600()
{
// [ D6H,0,0x00]: 定時(shí)器2高字節(jié)
T2H = 0xFD;
// [ D7H,0,0x00]: 定時(shí)器2低字節(jié)
T2L = 0x8F;
}
void uart_init_28m_9600()
{
// [ D6H,0,0x00]: 定時(shí)器2高字節(jié)
T2H = 0xFD;
// [ D7H,0,0x00]: 定時(shí)器2低字節(jié)
T2L = 0x26;
}
void uart_init_32m_9600()
{
// [ D6H,0,0x00]: 定時(shí)器2高字節(jié)
T2H = 0xFC;
// [ D7H,0,0x00]: 定時(shí)器2低字節(jié)
T2L = 0xBE;
}
/*****************************************************************************/
/**
* \brief 通過修改IRTRIM和LIRTRIM調(diào)節(jié)內(nèi)部時(shí)鐘頻率
******************************************************************************/
void trim_freq(unsigned char trim, unsigned char litrim)
{
IRTRIM = trim;
LIRTRIM = litrim;
while(!(IRC24MCR & 0x01));
}
void PrintChar(unsigned char dat)
{
SBUF = dat;
while(!TI);
TI = 0;
}
void PrintHex(unsigned char hex)
{
PrintChar(hexTable[hex >> 4]);
PrintChar(hexTable[hex & 0xF]);
}
void PrintString(unsigned char *str)
{
while (*str != '\0')
{
SBUF = *str;
while(!TI);
TI = 0; /* clear */
str++;
}
}
void Delay100ms() //@22.1184MHz
{
unsigned char j, k;
j = 100;
k = 228;
do
{
while (--k);
} while (--j);
}
void DetectItrim(unsigned char *str)
{
unsigned char i, j;
do
{
j = 3;
do
{
trim_freq(i, j);
PrintHex(IRTRIM);
PrintChar(0x20);
PrintHex(LIRTRIM);
PrintChar(0x20);
PrintString(str);
Delay100ms();
} while (--j);
} while(--i);
}
void main()
{
clock_init();
while(1)
{
uart_init_18m_9600();
DetectItrim(" 18MHz 9600\r\n");
uart_init_22m1184_9600();
DetectItrim(" 22.1184MHz 9600\r\n");
uart_init_24m_9600();
DetectItrim(" 24MHz 9600\r\n");
uart_init_28m_9600();
DetectItrim(" 28MHz 9600\r\n");
uart_init_32m_9600();
DetectItrim(" 32MHz 9600\r\n");
}
}
復(fù)制代碼
作者:
單片機(jī)愛好者223
時(shí)間:
2021-11-16 11:33
51 用linux啊,,,簡(jiǎn)直沒誰(shuí)了。。。。
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1