最近要做一个手持下载器,用AT89S52通过JTAG方式给STM32下载程序。由于原来没做过相关的东西,所以网上找了一下相关的资料,照着现有的历程测试了下,发现的以下几个问题
1,STM32对应的BSD文件中,写着
attribute INSTRUCTION_OPCODE of STM32F103C8: entity is
"BYPASS (11111)," &
"EXTEST (00000)," &
"SAMPLE (00010)," &
"PRELOAD (00010)," &
"IDCODE (00001)";
那么我用IDCODE指令去读取CPUID,代码如下
//P1_3 P1_5 P1_6引脚对应TDI TCK TMS
//P3_0对应TDO
#define JTAG_DELAY() _nop_()
#define JTAG_GET_TDO() ((P3_0==1) ? 1:0)
void nvdJTAG_Set(unsigned char Control)
{
P1 = Control;
}
void JTAG_ReadId(void)
{
int i;
char id[32];
JTAG_RunTestldleState();
nvdJTAG_Set(TDI_H | TMS_H | TCK_L);JTAG_DELAY();
nvdJTAG_Set(TDI_H | TMS_H | TCK_H);JTAG_DELAY(); // Select-DR Scan Status
nvdJTAG_Set(TDI_H | TMS_H | TCK_L);JTAG_DELAY();
nvdJTAG_Set(TDI_H | TMS_H | TCK_H);JTAG_DELAY(); // Select-IR Scan Status
nvdJTAG_Set(TDI_H | TMS_L | TCK_L);JTAG_DELAY();
nvdJTAG_Set(TDI_H | TMS_L | TCK_H);JTAG_DELAY(); // Capture-IR Status
nvdJTAG_Set(TDI_H | TMS_L | TCK_L);JTAG_DELAY();
nvdJTAG_Set(TDI_H | TMS_L | TCK_H);JTAG_DELAY(); // Shift-IR Status
//STM32F103XX IDCODE Instruction "00001"
nvdJTAG_Set(TDI_H | TMS_L | TCK_L);JTAG_DELAY();
nvdJTAG_Set(TDI_H | TMS_L | TCK_H);JTAG_DELAY(); // '1'
nvdJTAG_Set(TDI_L | TMS_L | TCK_L);JTAG_DELAY();
nvdJTAG_Set(TDI_L | TMS_L | TCK_H);JTAG_DELAY(); // '0'
nvdJTAG_Set(TDI_L | TMS_L | TCK_L);JTAG_DELAY();
nvdJTAG_Set(TDI_L | TMS_L | TCK_H);JTAG_DELAY(); // '0'
nvdJTAG_Set(TDI_L | TMS_L | TCK_L);JTAG_DELAY();
nvdJTAG_Set(TDI_L | TMS_L | TCK_H);JTAG_DELAY(); // '0'
nvdJTAG_Set(TDI_L | TMS_H | TCK_L);JTAG_DELAY();
nvdJTAG_Set(TDI_L | TMS_H | TCK_H);JTAG_DELAY(); // '0', //Exit1-IR
nvdJTAG_Set(TDI_H | TMS_H | TCK_L);JTAG_DELAY();
nvdJTAG_Set(TDI_H | TMS_H | TCK_H);JTAG_DELAY(); // Update_IR
nvdJTAG_Set(TDI_H | TMS_H | TCK_L);JTAG_DELAY();
nvdJTAG_Set(TDI_H | TMS_H | TCK_H);JTAG_DELAY(); // Select-DR-Scan
nvdJTAG_Set(TDI_H | TMS_L | TCK_L);JTAG_DELAY();
nvdJTAG_Set(TDI_H | TMS_L | TCK_H);JTAG_DELAY(); //Capture-DR
nvdJTAG_Set(TDI_H | TMS_L | TCK_L);JTAG_DELAY();
nvdJTAG_Set(TDI_H | TMS_L | TCK_H);JTAG_DELAY(); //Shift-DR
// Read IDcode..
for( i=0 ; i<=30 ; i++) {
nvdJTAG_Set(TDI_H | TMS_L | TCK_L);JTAG_DELAY();
nvdJTAG_Set(TDI_H | TMS_L | TCK_H);JTAG_DELAY(); //Shift-DR
id
= (char)JTAG_GET_TDO();
}
nvdJTAG_Set(TDI_H | TMS_H | TCK_L);JTAG_DELAY();
nvdJTAG_Set(TDI_H | TMS_H | TCK_H);JTAG_DELAY(); //Exit1_DR
id = (char)JTAG_GET_TDO();
nvdJTAG_Set(TDI_H | TMS_H | TCK_L);JTAG_DELAY();
nvdJTAG_Set(TDI_H | TMS_H | TCK_H);JTAG_DELAY(); // Update_DR
nvdJTAG_Set(TDI_H | TMS_L | TCK_L);JTAG_DELAY(); //
nvdJTAG_Set(TDI_H | TMS_L | TCK_H);JTAG_DELAY(); // Run-Test/Idle
nvdJTAG_Set(TDI_H | TMS_L | TCK_L);JTAG_DELAY();
nvdJTAG_Set(TDI_H | TMS_L | TCK_H);JTAG_DELAY(); // Run-Test/Idle
nvdJTAG_Set(TDI_H | TMS_L | TCK_L);JTAG_DELAY();
nvdJTAG_Set(TDI_H | TMS_L | TCK_H);JTAG_DELAY(); // Run-Test/Idle
}
可是取到的32位ID值,每一位总是常为1,不是正确值。现在STM32的板子可以通过ULink正常写程序。
请问这是怎么回事,是不是JTAG_DELAY()函数的延时不对?还是硬件上需要有特殊的电路?
此帖出自小平头技术问答
用IDCODE取得芯片识别码之后,对stm32内部Flash进行擦写怎么进行
BSD文件里没写管脚或者边界扫描链和寄存器的关系
有人说是 先向指令寄存器写地址,然后操作数据寄存器,数据寄存器的值就传到相应地址上
我理解的是 向指令寄存器写的只能是JTAG的10条指令
请高人指教
一周热门 更多>