Stm32ISP 2

读出stm32芯片的唯一id 并写入 0x8000000地址中


// JkIsp.cpp : Defines the entry point for the console application.

//
#include "stdafx.h"
HANDLE m_hIDComDev;        //串口句柄
int OpenCom()
{
    DCB dcb = { 0 };
    m_hIDComDev = CreateFile("COM2", GENERIC_READ | GENERIC_WRITE, 0, NULL,
        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);  //打开串口
    if (m_hIDComDev == INVALID_HANDLE_VALUE)
    {
        printf("打开串口失败!\n");
        return 1;
    }
    //GetCommTimeouts(m_hIDComDev, &CommTimeOuts);    //获取串口超时配置
    //总超时=时间系数×要求读/写的字符数+时间常量
    //读总超时=ReadTotalTimeoutMultiplier×10+ReadTotalTimeoutConstant
    COMMTIMEOUTS CommTimeOuts =// 串口超时控制参数
    {
        50,        // 读字符间隔超时时间
        1,        // 读操作时每字符的时间
        50,        // 基本的(额外的)读超时时间
        2,        // 写操作时每字符的时间
        10        // 基本的(额外的)写超时时间
    };
    SetCommTimeouts(m_hIDComDev, &CommTimeOuts);    //设置超时
    dcb.DCBlength = sizeof(DCB);
    GetCommState(m_hIDComDev, &dcb);                //
    dcb.BaudRate = 115200;        //设置波特率  
    dcb.ByteSize = 8;            //设置校验字节
    dcb.StopBits = 0;            //停止字节1位        0/1 1/1.5 2/2
    dcb.Parity = EVENPARITY;    //偶校验
    if (!SetCommState(m_hIDComDev, &dcb))//设置串口和收发缓冲器的大小
    {
        DWORD dwError = GetLastError();
        CloseHandle(m_hIDComDev);
        return 2;
    }

    if (!SetupComm(m_hIDComDev, 1024, 1024))
    {
        DWORD dwError = GetLastError();
        CloseHandle(m_hIDComDev);
        return 3;
    }

    PurgeComm(m_hIDComDev, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_TXABORT | PURGE_RXABORT);//清收发缓冲器
    return 0;
}

int  CloseCom()
{
    CloseHandle(m_hIDComDev);
    return 1;
}

enum ProCmd{
    eProGetVC = 0,        //获取版本已经命令集
    eProGetVP = 1,        //获取版本以及保护状态
    eProGetID,            //读取ic芯片型号
    eProRdMem = 0x11,        //读取memory
    eProGo = 0x21,        //程序跳转指令
    eProWrMem = 0x31,        //最多写入256个字节
    eProErase0 = 0x43,
    eProErase1 = 0x44,
    eProWrPt = 0x63,        //写保护
    eProWrUPt = 0x73,        //解除写保护
    eProRdPt = 0x82,
    eProRdUPt = 0x92,

    eProEraseFull=0xff,
};

#define ACK        0x79
#define NACK    0x1F

int RecData(BYTE *pt)
{
    BOOL bReadState;
    DWORD  readcnt;
    DWORD len=0;
    bReadState = ReadFile(m_hIDComDev, &len, 1, &readcnt, NULL);
    if (bReadState == TRUE)
    {
        ++len;
        bReadState = ReadFile(m_hIDComDev, pt, len + 1, &readcnt, NULL);        //读出字节数+ack
        if (bReadState == FALSE || readcnt != len + 1 || pt[len] != ACK)    return 0;
        return len;
    }
    return 0;
}

BOOL WriteProCmd(BYTE cmd)
{
    BYTE cmdbuf[2];
    DWORD writecnt, readcnt, cnt = 0;
    BYTE readbuf[1024] = { NACK };
    BOOL bReadState;
    cmdbuf[0] = cmd;
    cmdbuf[1] = cmd ^ 0xff;
    PurgeComm(m_hIDComDev, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_TXABORT | PURGE_RXABORT);    //清收发缓冲器
    do{
        WriteFile(m_hIDComDev, &cmdbuf, 2, &writecnt, NULL);
        bReadState = ReadFile(m_hIDComDev, readbuf, 1, &readcnt, NULL);
    } while (++cnt < 4 && ((bReadState == FALSE) || (readbuf[0] != ACK && readbuf[0] != NACK)));
    return (readbuf[0] == ACK);
}

BOOL TestLink()
{
    BYTE cmdbuf[1];
    DWORD writecnt, readcnt,cnt=0;
    BYTE readbuf[16];
    BOOL bReadState;
    cmdbuf[0] = 0x7F;
    PurgeComm(m_hIDComDev, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_TXABORT | PURGE_RXABORT);    //清收发缓冲器
    do{
        WriteFile(m_hIDComDev, &cmdbuf, 1, &writecnt, NULL);
        bReadState = ReadFile(m_hIDComDev, readbuf, 1, &readcnt, NULL);
    } while (++cnt < 100 && ((bReadState == FALSE) || readbuf[0] != 0x79));
    return (cnt < 100);
}

BYTE m_EraseCode = ProCmd::eProErase0;
BOOL GetVersionAndCmd()
{
    int rdCnt=0,i;
    BYTE buf[256];
    if (WriteProCmd(ProCmd::eProGetVC) == TRUE)
    {
        rdCnt = RecData(buf);
        if (rdCnt != 0)
        {
            printf("boot version:%X\r\n", buf[0]);
            for (i = 1; i < rdCnt; i++)
            {
                if (buf[i] == ProCmd::eProErase0 || buf[i] == ProCmd::eProErase1)
                {
                    m_EraseCode = buf[i];
                    break;
                }
            }
            printf("Erase Mode:%d\r\n", m_EraseCode - ProCmd::eProErase0);
        }
        else printf("Get version and command set failed\r\n");
    }
    else printf("Get version and command set failed\r\n");
    return (rdCnt != 0);
}

BOOL EraseFlash(void)
{
    BOOL ret = FALSE;
    if (WriteProCmd(m_EraseCode) == TRUE)
    {
        if (WriteProCmd(ProCmd::eProEraseFull))
        {
            printf("Erase successful\r\n");
            ret = TRUE;
        }
    }
    if (ret == FALSE)
    {
        printf("Erase failed\r\n");
    }
    return ret;
}

BOOL ReadMemory(DWORD addr, int len, BYTE *pt)
{
    BYTE addr2byte[5];
    DWORD optcnt;
    BYTE readbuf[2];
    BOOL bReadState;
    int i;
    if (WriteProCmd(ProCmd::eProRdMem))
    {
        addr2byte[4] = 0x00;
        for (i = 0; i < 4; i++)
        {
            addr2byte[3 - i] = addr & 0xff; addr >>= 8;
            addr2byte[4] ^= addr2byte[3 - i];
        }

        WriteFile(m_hIDComDev, &addr2byte, 5, &optcnt, NULL);
        bReadState = ReadFile(m_hIDComDev, readbuf, 1, &optcnt, NULL);
        if (bReadState == FALSE || readbuf[0] != ACK)
        {
            return FALSE;
        }

        addr2byte[0] = len-1;                    //要接收的长度减去一 为了能最大接收256 个字节
        addr2byte[1] = addr2byte[0] ^ 0xff;
        WriteFile(m_hIDComDev, &addr2byte, 2, &optcnt, NULL);
        bReadState = ReadFile(m_hIDComDev, readbuf, 1, &optcnt, NULL);
        if (bReadState == FALSE || readbuf[0] != ACK)
        {
            return FALSE;
        }

        bReadState = ReadFile(m_hIDComDev, pt, len, &optcnt, NULL);
        if (bReadState == FALSE || len != optcnt)    return FALSE;
        return TRUE;
    }
    return FALSE;
}

BOOL WriteMemory(DWORD addr, int len, BYTE *pt)
{
    BYTE wr2byte[252];                //写入的字节数 1  写入的数据 256 校验和 前面包括 长度的抑或
    DWORD optcnt;
    BYTE readbuf[4];
    BOOL bReadState;
    int i;
    if (WriteProCmd(ProCmd::eProWrMem))
    {
        wr2byte[4] = 0x00;
        for (i = 0; i < 4; i++)
        {
            wr2byte[3 - i] = addr & 0xff; addr >>= 8;
            wr2byte[4] ^= wr2byte[3 - i];
        }
        WriteFile(m_hIDComDev, &wr2byte, 5, &optcnt, NULL);
        bReadState = ReadFile(m_hIDComDev, readbuf, 1, &optcnt, NULL);
        if (bReadState == FALSE || readbuf[0] != ACK)
        {
            return FALSE;
        }

        wr2byte[0] = len - 1;
        wr2byte[len + 1] = wr2byte[0];
        for (i = 0; i < len; i++)
        {
            wr2byte[i + 1] = pt[i];
            wr2byte[len + 1] ^= pt[i];
        }
        WriteFile(m_hIDComDev, &wr2byte, len+2, &optcnt, NULL);
        bReadState = ReadFile(m_hIDComDev, readbuf, 1, &optcnt, NULL);
        if (bReadState == FALSE || readbuf[0] != ACK)
        {
            return FALSE;
        }
        return TRUE;
    }
    return FALSE;

}


int _tmain(int argc, _TCHAR* argv[])
{
    int ret,cnt=0;
    DWORD Stm32ID[3];
    ret = OpenCom();
    if (ret == 0)
    {
        if(TestLink() == FALSE)
        {
            printf("连接STM32失败\r\n");
            return 1;
        }
    
        GetVersionAndCmd();

        if(EraseFlash() == false)
        {
            ret = WriteProCmd(eProRdUPt);
            if (ret == 0)
            {
                printf("解锁失败\r\n");
                return 2;
            }
            if (TestLink() == FALSE)
            {
                printf("二次连接STM32失败\r\n");
                return 3;
            }
            EraseFlash();
        }

        if (ReadMemory(0x1FFFF7E8, 12, (BYTE*)Stm32ID) == FALSE)
        {
            printf("Read Stm32 ID failed\r\n");
            return 4;
        }
        printf("STM32ID:%08X %08X %08X\r\n", Stm32ID[0], Stm32ID[1], Stm32ID[2]);


        WriteMemory(0x08000000, 12, (BYTE*)Stm32ID);


        CloseCom();
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值