1. 飛思卡爾單片機如何像51單片機那樣下載程序(燒寫hex文件)而不讓別人看到源程序
飛思卡爾單片機下載程序沒那麼簡單的,需要專門的編程器,網上可以買到。現在國內做飛思卡爾的比較好的就是清華大學的。
2. 這個飛思卡爾的晶元需要寫程序嗎
如果買來就是有程序的就不需要寫了。如果是可編程的就需要寫自己的程序的。
3. 飛思卡爾mc9s12xf512的用eeprom讀寫數據的完整程序代碼該怎麼寫呢(只要這款晶元的)
voidEEPROM_erasure(UINT16number)//清除操作函數
{
UINT16*erase;
//erase=(unsignedchar*)(0x400+number);
erase=(UINT16*)(number);
*erase=0xff;
DisableInterrupts;
while(!(ECLKDIV&0x80))
{}
while(!(ESTAT&0x80))
{}
while(!(EPROT&0x80))
{}
ECMD=0x40;
ESTAT|=0x80;
while(!(ESTAT&0x40))
{}
EnableInterrupts;;
}
voidEEPROM_write(UINT16code,UINT16number)//寫操作
{
UINT16*eeaddr;//對EEPROM進行寫操作時的地址
/*
allow_calibration=0;
calibration=1;
*/
DisableInterrupts;
eeaddr=(UINT16*)(number);
while(!(ECLKDIV&0x80))//判斷ECLKDIV是否被寫入,是向下進行,否原地等待?
{}
while(!(ESTAT&0x80))//判斷緩沖區是否准備好,准備好則向下進行,沒有準備好則原地等待?
{}
while(!(EPROT&0x80))//判斷EEPROM是否允許被寫入,允許向下進行,不允許則原地等待?
{}
*eeaddr=code;
ECMD=0x20;
ESTAT|=0x80;
while(!(ESTAT&0x40))//判斷EEPROM是否被寫入,是向下進行,否原地等待;
{}
EnableInterrupts;
return;
}
*/
UINT16EEPROM_read(UINT16add)//讀操作
{UINT16*erase;
UINT16m;
calibration=0;
DisableInterrupts;
erase=(UINT16*)(add);
m=*erase;
EnableInterrupts;
returnm;}
4. 飛思卡爾單片機程序怎樣讀出
單片機解密又叫單片機破解,晶元解密,IC解密,但是這嚴格說來這幾種稱呼都不科學,但已經成了習慣叫法,我們把CPLD解密,DSP解密都習慣稱為單片機解密。單片機只是能裝載程序晶元的其中一個類。能燒錄程序並能加密的晶元還有DSP,CPLD,PLD,AVR,ARM等。當然具存儲功能的存儲器晶元也能加密,比如DS2401 DS2501 AT88S0104 DM2602 AT88SC0104D等,當中也有專門設計有加密演算法用於專業加密的晶元或設計驗證廠家代碼工作等功能晶元,該類晶元業能實現防止電子產品復制的目的。
5. 能否讀出飛思卡爾單片機中未加密的程序
可以的,就算加密的都可以讀出來。現在有專門破解單片機的,可以花錢找人破解。
6. 飛思卡爾MC9S08GB60單片機怎麼解密
大部分單片機為防止解密都有很多措施。建議還是努力學習吧,不要想破解了。破解有硬體破解,和軟體破解,都需要大量時間,以及很專業知識。網路一下,會有專業破解的,可價格也擺在那了。
7. 怎樣用CodeWarrior讀出晶元的程序
利用向導創建一個新工程項目
•在新項目中加入或刪除文件
•調試
•啟動程序•PRM 文件設置
•如何對IO 及寄存器進行操作
•如何寫中斷程序
•嵌入式編程注意事項•Codewarrior 定購信息
8. 飛思卡爾程序
我這只有舵機,攝像頭,和主程序,但是只是框架,要等調試。可以參考哈
#ifndef _WATCH_H_ //頭文件保護
#define _WATCH_H_
#ifndef ULONG
#define ULONG unsigned long
#define UCHAR unsigned char
#define UINT unsigned int
#endif
#define ROAD_MAX 10
////////////////代設值
#define MP0 //捕捉象素引腳
#define HREF //捕捉行中斷引腳
//////////////////
static unsigned char Colors[10][48]; //象素數組
static unsigned char JudgeMax; //最大象素
static unsigned char JudgeMin; //最小象素
unsigned char Over; //中斷函數處理完成
//使用數組後要清零
struct ROADS
{
unsigned char LeftRight; //1 left, 0 right 2 表示沒檢測到黑線 4表示起始線
unsigned int road; //轉向率,0表示直線或則沒檢測到黑線
}Roads[10]; //沒檢測到黑線一般為前方有大於90度的彎,
//行駛一會後數組會更新,不會因此丟掉跑道
unsigned long RoadLength; //mm單位
void GetRoads(); //取象素
void ProcessRoads(); //取轉向率
void delay(UINT); //延時函數
void ColorToRoads(UINT); //2值化與賦值
#endif //_WATCH_H_
以下為實現文件:
//watch.c
#include <hidef.h> /* common defines and macros */
#include <MC9S12XS128.h> /* derivative information */
#include "watch.h"
#pragma CODE_SEG NON_BANKED
#pragma TRAP_PROC
void GetRoads() //場中斷服務函數
{
UINT i;
UINT Href= 0;
delay(5);
while(HREF)
{
if(Href>= 270) //點讀取完畢,退出循環
break;
if((270-Href)%21!= 0 || Href< 60) //取60-270行中平均間隔的行數,共30行
{
Href++;
while(HREF); //等待此行掃描結束
while(!HREF); //等待新行開始掃描
continue;
}
delay(...); //根據調式結果具體設置
for(i= 0; i< 48; i++)
{
Colors[((270-Href)%21)][i]= MP0; //讀取引腳數據,後來會根據串口還是並口讀取做相應修改
if(MP0> judgeMax) //取最大最小值
JudgeMax= MP0;
if(MP0< JudgeMin)
JudgeMin= MP0;
delay(...); //具體設置
}
Href++;
while(HREF);
while(!HREF); //等待行中斷結束
}
Over= 1; //中斷函數處理完成
}
#pragma CODE_SEG DEFAULT
void ColorToRoads(UINT Href)
{
UINT i;
UINT temp; //用於起始線判斷
UINT temp2;
UINT temp3;
UCHAR Judge; //平均厥值
UINT j= 0;
UINT m_nCount= 0;
Judge= (JudgeMax+ JydgeMin)/2;
Roads[Href].road= 0;
Roads[Href].LeftRight= 0;
for(i= 0; i<48; i+= 3)
{
if(Colors[i]<= Judge||
Colors[i+ 1]<= Judge||
Colors[i+ 2]<= Judge)
{
Roads[Href].road&= (0x8000>> (UCHAR)j); //相應位賦值為1
m_nCount++;
}
j++;
}
if(Roads[Href].road== 0x00)
{
Roads[Href].LeftRight= 0x02; //沒有捕捉到黑線設置2
}
if(m_nCount> 1) //若黑點數大於1,從左向右數出連續的點中的中間點
{
j= 0;
i= 0;
while(!(Roads[Href].road& (0x8000>>(UCHAR)i)))
{
i++;
}
j= i;
while((Roads[Href].road& (0x8000>>(UCHAR)i))
{
i++;
if(i> 15)
break;
}
if(i< 15) //起始線判斷
{
temp= i;
while(!(Roads[Href].road& (0x8000>>(UCHAR)temp)))
{
temp++;
temp2= temp;
}
if(temp< 15)
{
while((Roads[Href].road& (0x8000>>(UCHAR)temp))
{
temp++;
temp3= temp;
if(temp> 15)
break;
}
if(temp< 15)
{
while(!(Roads[Href].road& (0x8000>>(UCHAR)temp)))
{
temp++;
}
if(temp< 15)
{
Roads[Href].LeftRight= 0x04;
Roads[Href].road&= 0x8000>>(UCHAR)((temp2+ temp3)/2);
return;
}
}
}
}
Roads[Href].road&= 0x8000>>(UCHAR)((i+j)/2);
}
}
void ProcessRoads() //路徑處理函數,在主函數中調用
{
int i;
for (i= 0;i< 10; i++)
{
ColorToRoads(i);
}
}
void delay(UINT m) //延時函數根據調試結果相應做改動
{
UINT i;
UINT j;
for(i= 0; i< m; i++)
{
for(j= 0; j< 200; j++)
}
}
再下面就是主函數實現文件:
#include <hidef.h> /* common defines and macros */
#include <MC9S12XS128.h> /* derivative information */
#pragma LINK_INFO DERIVATIVE "mc9s12xs128"
#include "watch.h" //攝像頭
#include "TurnAround.h" //舵機
//#include "..." //直流電機
//#include "..." //測速模塊
#ifndef TRUE
#define TRUE 1
#define FLASE 0
#endif
#define ULONG unsigned long
#define UCHAR unsigned char
#define UINT unsigned int
#define LITTLE
#define LARGE
//////////////////////全局變數
UCHAR m_nCount; //圈數計算
UCHAR m_nCount2;
////////////////////////////////函數定義
void init(); //初始化函數 待修改
UCHAR CheckRoad(UCHAR*,UCHAR*); //第1參數返回第幾個元素開始
//第2個參數返回第幾個元素結束
//0 直線, 0x11有小彎道, 0x21大彎道, 0x31終點
void CarRun(UCHAR, UCHAR, UCHAR); //小車行駛函數
#pragma CODE_SEG NON_BANKED
#pragma TRAP_PROC
void Int_TimerOverFlow(void) //32MHz TCNT 50000--200ms
{
static int m= 0;
if(m== 15) //3秒
{
m_nCount2= 0;
TSCR1_TEN= 0; //關定時器
TFLG2_TOF = 1;
}
m++;
}
#pragma CODE_SEG DEFAULT
void TimerInit()
{
TIOS= 0x00;
TSCR2_PR= 7; //默認情況下是32MHz bus clock,所以分頻後主時鍾為 0.25MHz
TSCR2_TOI= 1; //OverFlow方式
TCNT= 65535- 50000;
TSCR1_TEN= 1; //開定時器
}
////////////////////////////////
void main() //主程序
{
UCHAR ret;
UCHAR number1= 0;
UCAHR number2= 0;
init();
while(1)
{
while(over); //等待掃描完畢
over= 0;
IRQCR_IRQEN= 0; //關外部中斷IRQ
ProcessRoads(); //interface of watch.h
ret= CheckRoad(&number1, &number2); //檢測路徑
if(ret== 0x31)
break;
CarRun(number1, number2, ret);
}
PWME_PWME1= 0; //關閉PWM
while(1);
}
void init()
{
IRQCR_IRQE= 1; //下降沿觸發IRQ
PE1= 1;
EnableInterrupts; //開總中斷
INTCR_IRQEN= 1;
PWMInit(); //舵機初始化
Speed(MAX);
}
UCHAR CheckRoad(UCHAR* number1, UCHAR number2)
{
int i;
int sub= 0;
int psub= 0;
int temp;
bool flag;
UCHAR ret;
i= 0;
m_nCount2++;
while(!Roads[i].road)
{
i++;
}
*number1= i;
if(Roads[i].road>= Roads[i+ 1].road)
{
flag= TRUE;
psub= Roads[0].road- Roads[1].road;
}
else
{
flag= FALSE;
psub= Roads[1].road- Roads[0].road;
}
for(; i< 9; i++)
{
if(Roads[i].LeftRight== 0x04)
{
if(m_nCount2== 0)
{
m_nCount2= 1;
m_nCount++;
TimerInit();
}
}
if(m_nCount== 3)
{
Speed(0);
ret= 0x31;
goto _RET;
}
if(Roads[i+ 1].road== 0)
{
break;
}
if(flag)
{
sub= Roads[i].road- Roads[i+ 1].road;
}
else
{
sub= Roads[i+ 1].road- Roads[i].road;
}
sub>>= (UCHAR)i;
if(sub>= psub) //取差值
temp= sub- psub;
else
temp= psub- sub;
if(temp> LARGE) //大彎道
{
ret= 0x21;
while(Roads[i].road!= 0)
{
i++;
*number2= i;
if(i> 9)
break;
}
goto _RET;
}
if(temp> LITTLE) //小彎道
{
ret= 0x11;
while(Roads[i].road!= 0)
{
i++;
*number2= i;
if(i> 9)
break;
}
goto _RET;
}
*number2= i;
psub= sub;
}
_RET:
return ret;
}
void CarRun(UCHAR number1, UCHAR number2, UCHAR ret)
{
int end= Roads[number2].road;
Turn(number2- number1, end- 0x100, Roads[number2].LeftRight, ret); //舵機函數
IRQCR_IRQEN= 1; //開IRQ
}
下面為舵機頭文件:
//TurnAround.h
#ifndef _TURNAROUND_H_ //頭文件保護
#define _TURNAROUND_H_
void Turn(unsigned char, unsigned int, unsigned char, unsigned char); //轉角函數
void PWMInit(); //優先初始化
#endif
再以下為實現文件:(表內容待實驗後求得)
//TurnAround.c
#include <hidef.h> /* common defines and macros */
#include <MC9S12XS128.h> /* derivative information */
#pragma LINK_INFO DERIVATIVE "mc9s12xs128"
#include "TurnAround.h"
#include "..." //直流電機
#ifndef ULONG
#define ULONG unsigned long
#define UCHAR unsigned char
#define UINT unsigned int
#endif
/////////////////////////轉角定義
#define RIGHT60 1083
#define RIGHT45 1000
#define RIGHT30 917
#define RIGHT15 833
#define RIGHT5 778
#define MIDDLE 750
#define LEFT5 722
#define LEFT15 667
#define LEFT30 583
#define LEFT45 500
#define LEFT60 417
/////////////////////////速度定義
#define SPEED0 //直線速度
#define SPEED5
#define SPEED15
#define SPEED30
#define SPEED45
#define SPEED60
//PWM查詢表 7*10*2
static UINT PWMTable[]=
{
//Left
LEFT60, LEFT60, LEFT60, LEFT60, LEFT60, LEFT60, LEFT60, LEFT60, LEFT60, LEFT60,
LEFT60, LEFT60, LEFT60, LEFT60, LEFT60, LEFT60, LEFT60, LEFT60, LEFT60, LEFT60,
LEFT60, LEFT60, LEFT60, LEFT60, LEFT60, LEFT60, LEFT60, LEFT60, LEFT60, LEFT60,
LEFT60, LEFT60, LEFT60, LEFT60, LEFT60, LEFT60, LEFT60, LEFT60, LEFT60, LEFT60,
LEFT60, LEFT60, LEFT60, LEFT60, LEFT60, LEFT60, LEFT60, LEFT60, LEFT60, LEFT60,
LEFT60, LEFT60, LEFT60, LEFT60, LEFT60, LEFT60, LEFT60, LEFT60, LEFT60, LEFT60,
LEFT60, LEFT60, LEFT60, LEFT60, LEFT60, LEFT60, LEFT60, LEFT60, LEFT60, LEFT60,
//Right
RIGHT60, RIGHT60, RIGHT60, RIGHT60, RIGHT60, RIGHT60, RIGHT60, RIGHT60, RIGHT60, RIGHT60,
RIGHT60, RIGHT60, RIGHT60, RIGHT60, RIGHT60, RIGHT60, RIGHT60, RIGHT60, RIGHT60, RIGHT60,
RIGHT60, RIGHT60, RIGHT60, RIGHT60, RIGHT60, RIGHT60, RIGHT60, RIGHT60, RIGHT60, RIGHT60,
RIGHT60, RIGHT60, RIGHT60, RIGHT60, RIGHT60, RIGHT60, RIGHT60, RIGHT60, RIGHT60, RIGHT60,
RIGHT60, RIGHT60, RIGHT60, RIGHT60, RIGHT60, RIGHT60, RIGHT60, RIGHT60, RIGHT60, RIGHT60,
RIGHT60, RIGHT60, RIGHT60, RIGHT60, RIGHT60, RIGHT60, RIGHT60, RIGHT60, RIGHT60, RIGHT60,
RIGHT60, RIGHT60, RIGHT60, RIGHT60, RIGHT60, RIGHT60, RIGHT60, RIGHT60, RIGHT60, RIGHT60
};
//延時查詢表 6*6
static UNIT DelayTable[]=
{
0,0,0,0,0,0,
0,0,0,0,0,0,
0,0,0,0,0,0,
0,0,0,0,0,0,
0,0,0,0,0,0,
0,0,0,0,0,0
}
void PWMInit() //32HHz
{
PWMCTL_CON01= 1; //0, 1合為16bit
PWMCAE_CAE1= 1; //Center mode
PWMCLK_PLCK1= 0; //Clock A
PWMPRCLK_PCKA= 5; //Clock A= 32MHz/32= 1MHz
PWMPOL_PPOL1= 0; //開始為低電壓
PWMPER0,1= 10000; //50Hz PWM輸出
PWMDTY0,1= MIDDLE; //(10000- 750)* 100%= 92。5%占空比,1.5ms高電壓時間
PWME_PWME1= 1; //enable
}
static void delay(int ms)
{
int ii,jj;
if (ms<1) ms=1;
for(ii=0;ii<ms;ii++)
for(jj=0;jj<2770;jj++); //32MHz--1ms
}
static void SetPWM(UINT m_nPWM) //PWM設置
{
PWMDTY0,1= m_nPWM;
}
//number 9種情況,sub 7種情況,LeftRight 2中情況
//共128種情況,採用模糊控制暫時歸納為11種情況
//11種情況將填入表中提供查詢,11中情況分別為:
//左右5, 15, 30, 45, 60度
//和正中間0度
static UINT GetPWM(UCHAR number, UINT sub, UCHAR LeftRight)
{
switch(sub) //通過sub算出索引值
{
case 0x8000- 0x0100:
case 0x0100- 0x0001;
case 0x0100- 0x0002;
sub= 0;
break;
case 0x4000- 0x0100:
case 0x0100- 0x0004:
sub= 1;
break;
case 0x2000- 0x0100:
case 0x0100- 0x0008:
sub= 2;
break;
case 0x1000- 0x0100:
case 0x0100- 0x0010:
sub= 3;
break;
case 0x0800- 0x0100:
case 0x0100- 0x0020:
sub= 4;
break;
case 0x0400- 0x0100:
case 0x0100- 0x0040:
sub= 5;
break;
case 0x0200- 0x0100:
case 0x0100- 0x0100:
case 0x0100- 0x0080:
sub= 6;
break;
}
return PWMTable[number+ sub* 10+ LeftRight* 70];
}
//通過m_nPWM來改變速度,並返回改變的值
static UINT ChangeSpeed(UINT m_nPWM)
{
UINT m_nSpeed;
switch(m_nPWM) //根據m_nPWM 調節速度
{
case LEFT60:
Speed(SPEED60);
m_nSpeed= SPEED60;
break;
case LEFT45:
Speed(SPEED45);
m_nSpeed= SPEED45;
break;
case LEFT30:
Speed(SPEED30);
m_nSpeed= SPEED30;
break;
case LEFT15:
Speed(SPEED15);
m_nSpeed= SPEED15;
break;
case LEFT5:
Speed(SPEED5);
m_nSpeed= SPEED5;
break;
case MIDDLE:
Speed(SPEED0);
m_nSpeed= SPEED0;
break;
case RIGHT60:
Speed(SPEED60);
m_nSpeed= SPEED60;
break;
case RIGHT45:
Speed(SPEED45);
m_nSpeed= SPEED45;
break;
case RIGHT30:
Speed(SPEED30);
m_nSpeed= SPEED30;
break;
case RIGHT15:
Speed(SPEED15);
m_nSpeed= SPEED15;
break;
case RIGHT5:
Speed(SPEED5);
m_nSpeed= SPEED5;
break;
}
return m_nSpeed;
}
//獲得查表時的索引值
UINT GetIndex(UINT m_nSpeed)
{
if(m_nSpeed<= SPEED60)
{
m_nSpeed= 0;
}
else if(m_nSpeed<= SPEED45)
{
m_nSpeed= 1;
}
else if(m_nSpeed<= SPEED30)
{
m_nSpeed= 2;
}
else if(m_nSpeed<= SPEED15)
{
m_nSpeed= 3;
}
else if(m_nSpeed<= SPEED5)
{
m_nSpeed= 4;
}
else
{
m_nSpeed= 5;
}
return m_nSpeed;
}
//m_nSpeed2為欲設值
//m_nSpeed為當前速度
UINT GetDelay(UINT m_nSpeed, UINT m_nSpeed2)
{
m_nSpeed= GetIndex(m_nSpeed);
m_nSpeed2= GetIndex(m_nSpeed2);
return DelayTable[m_nSpeed* 6+ m_nSpeed2];
}
void Turn(UCHAR number, UINT sub, UCHAR LeftRight, UCHAR ret)//ret not be used now
{
UINT m_nPWM;
UINT m_nSpeed;
UINT m_nSpeed2;
UINT m_nDelay; //延時參數
m_nPWM= GetPWM(number, sub, LeftRight);
m_nSpeed= GetSpeed() //測速模塊
m_nSpeed2= ChangeSpeed(m_nPWM);
if(m_nSpeed2> m_nSpeed)
m_nSpeed= m_nSpeed2- m_nSpeed;
else
m_nSpeed= m_nSpeed- m_nSpeed2;
SetPWM(m_nPWM); //轉角
m_nDelay= GetDelay(m_nSpeed, m_nSpeed2);
delay(m_nDelay); //根據速度和角度延時
SetPWM(MIDDLE); //舵機擺正
}
最後說哈,程序只差調試就可以,筐架就是這。我是湖北賽區的,7月就要比賽了,他們車還沒做好啊。
9. 飛思卡爾 mc9s12xs128 單片機 怎樣才可以 在EPROM 或者在 FASH 中 保存運行的參數
有相關資料可以參考的,你搜一下flash to epprom相關資料:
用Flash模擬EEPROM
本程序利用S08系列單片機的片內Flash模擬EEPROM。解決部分8位機沒有EEPROM導致在運用上的局限。本程序提供一個初始化函數和三個功能函數。用戶必須在調用功能函數前調用調用初始化函數。三個功能函數分別是位元組寫入、位元組讀取、EEPROM全擦除。用戶必須保證調用功能函數前有至少30Bate的棧空間。
本程序參考飛思卡爾公司提供的《在 HCS08 微控制器上使用 FLASH 存儲器模擬 EEPROM》。並在源程序的基礎上精簡了部分功能,減少了RAM使用量。並嘗試使用分頁機制確定EEPROM地址。
介面函數的EEPROM地址定址由頁地址和頁內偏移量組成。即把用戶定義的EEPROM分為若干個大小為256位元組的頁。其地址與FLASH地址的換算關系為:
FLASH真實地址=EEPROM空間起始地址+頁地址×256+頁內偏移地址
用戶在使用EEPROM是只用確定數據保存在EEPROM的相對地址即可。介面函數原型為:
EEPROM_WRITE_DATA(數據,頁地址, 頁內偏移地址);
Char EEPROM_READ_DATA(頁地址, 頁內偏移地址);
1. 程序流程分析與設計。
由於S08系列單片機在Flash寫入時序中不能進行任何的Flash讀操作,Flash寫入指令必須放到RAM中執行並關閉所有可屏蔽中斷。程序流程如圖13-1-?。
位元組寫入/.全擦除程序流程 位元組讀取程序流程
圖13-1-?
2.程序源代碼。此程序在CodeWarrior 6.0繼承編譯環境中編譯通過
/*****************************************************/
//河南工業大學Freescale MCU&DSP聯合實驗室
// 文件名:flash_program.h
// CPU :MC9S08AW60
// 版 本:v1.0
// 日 期:2008年8月12日
// 調試環境:CodeWarrior 6.0
// 作 者:曾 滔
// 描 述: 頭文件,用於保存初始化EEPROM設定、用戶定製參數、編譯器參數等信息。
/*****************************************************/
#include <hidef.h>
#include "derivative.h"
#include <stdio.h>
/*************flash編程指令(請勿改動)*****************/
#define BLACK_CHECK 0x05 //查空指令
#define BITE_PROGRAM 0x20 //位元組編程指令
#define BURST_PROGRAM 0x25 //快速編程指令
#define PAGE_ERASE 0x40 //頁擦除指令(1頁=512位元組)
#define MASS_ERASE 0x41 //全擦除指令
/******用戶定製參數(根據單片機型號和用戶flash使用情況定製)**********/
#define EEPROM_START_ADDRESS 0xE000 //EEPROM區起始地址。512B的倍數
#define EEPROM_PAGE_NUM 8 //EEPROM頁數。1page=256B
#define BUS_FREQUENCY 2000 //匯流排頻率。單位(KHz)
/********************編譯器相關參數**************************/
#define INT8U unsigned char //無符號位元組變數。根據編譯器更改。默認CodeWarrior 6.0
#define INT16U unsigned short int //無符號字變數。根據編譯器更改。默認CodeWarrior 6.0
/***********EEPROM API函數原型***********/
//初始化程序。此函數必須在使用EEPROM前調用。建議用戶在系統初始化是調用。
void INIT_EEPROM(void);
//EEPROM擦除函數。擦除所有EEPROM數據。
void EEPROM_ERASE(void);
//EEPROM位元組寫入函數。寫入一個位元組到EEPROM指定區域。
void EEPROM_WRITE_DATA(INT8U data,INT8U EEPROM_page,INT8U offset_address)
//EEPROM讀出函數。讀出一個指定的區域所保存的位元組的到函數返回值。
char EEPROM_READ_DATA(INT8U EEPROM_page,INT8U offset_address);
/****************************END************************************/
/*****************************************************/
//河南工業大學Freescale MCU&DSP聯合實驗室
// 文件名:flash_program.c
// C P U :MC9S08AW60
// 版 本:v1.0
// 日 期:2008年8月12日
// 調試環境:CodeWarrior 6.0
// 作 者:曾 滔
// 描 述:提供了一個初始化函數和三個功能函數供用戶調用,沒有可更改參數。
/*****************************************************/
#include "flash_program.h"
const INT8U FLASH_CODE[]={ // ; flash操作代碼
0x45, 0x18, 0x26, // LDHX #$1826 ; FCMD地址寫入H:X
0xA6, 0x00, // LDA #$00 ; 0x00為命令佔位符
0xF7, // STA ,X ; 將命令寫入FCMD命令緩存器
0x5A, // DECX ; 指針指向 FSTAT
0xF6, // LDA ,X ;
0xAA, 0x80, // ORA #$80 ;
0xF7, // STA ,X ; 置位FSTAT_FCBEF。啟動flash寫入命令
0xF6, // LDA ,X ; 等待3個時鍾周期(請勿刪除此代碼)
0xF6, // LDA ,X ; 讀取FSTAT
0xA5, 0x30, // BIT #$30
0x26, 0x05, // BNE *+6 ; 錯誤則返回
//LOOP
0xF6, // LDA ,X ; 等待寫操作結束
0xA5, 0x40, // BIT #$40
0x27, 0xFB, // BEQ *-3 ; 跳轉到LOOP
//EXIT:
0X81 //RTS ; 返回
};
/*********************初始化函數**********************************/
#if BUS_FREQUENCY >= 12000
void INIT_EEPROM(void){FCDIV=(((BUS_FREQUENCY/(8*175)))|0x40)-1;}
#endif
#if BUS_FREQUENCY < 12000
void INIT_EEPROM(void){FCDIV=(BUS_FREQUENCY/175)-1;}
#endif
/***********************EEPROM位元組寫入函數****************************/
void EEPROM_WRITE_DATA(INT8U data,INT8U EEPROM_page,INT8U offset_address)
{
INT16U address; //存放寫入地址
INT8U code_space[23]; //初始化代碼空間
if(EEPROM_page>=EEPROM_PAGE_NUM)return; //地址錯誤返回,保護用戶代碼
address=offset_address+EEPROM_page*256+EEPROM_START_ADDRESS; //地址轉化
(void)memcpy(code_space,FLASH_CODE,23); //復制flash操作代碼到RAM
code_space[4] = BITE_PROGRAM; //修改命令佔位符為寫入命令
DisableInterrupts; //關中斷
if (FSTAT&0x10){ //清錯誤標志
FSTAT = FSTAT|0x10;
}
_asm
{ //寫入初始化
LDHX address;
LDA data;
STA ,X; //寫入緩存
TSX;
JSR 2,x; //跳入RAM執行
}
EnableInterrupts; //開中斷
__RESET_WATCHDOG();
}
/********************EEPROM字讀取入函數********************************/
char EEPROM_READ_DATA(INT8U EEPROM_page,INT8U offset_address){
unsigned short int address; //地址變數
char rusult; //數據變數
address=offset_address+EEPROM_page*0x100+EEPROM_START_ADDRESS; //地址轉換
asm{
LDHX address;
LDA ,X; //讀取地址到數據變數
STA rusult;
}
__RESET_WATCHDOG();
return(rusult); //返回
}
/**********************EEPROM擦除函數********************************/
void EEPROM_ERASE(void)
{
INT16U address;
INT8U i; //循環變數
INT8U code_space[23];
for(i=0;i<(EEPROM_PAGE_NUM/2);i++){ //分頁擦除
address=i*0x200+EEPROM_START_ADDRESS;
(void)memcpy(code_space,FLASH_CODE,23); //復制flash操作代碼到RAM
code_space[4] = PAGE_ERASE; //修改命令佔位符為擦除命令
DisableInterrupts; //關中斷
if (FSTAT&0x10){ //清錯誤標志
FSTAT = FSTAT | 0x10;
}
_asm
{
LDHX address; //擦除地址寫入緩存
STA ,X;
TSX;
JSR 3,x; //跳入RAM執行
}
EnableInterrupts; //開中斷
__RESET_WATCHDOG();
}
}
/****************************END************************************/
/*****************************************************/
// 版權所有(c)河南工業大學
// 文件名:mian.c
// C P U :MC9S08AW60
// 版 本:v1.0
// 日 期:2008年8月12日
// 調試環境:CodeWarrior 6.0
// 作 者:曾 滔
// 描 述: 測試Flash模擬EEPROM程序。
/*****************************************************/
#include <hidef.h>
#include "derivative.h"
#include "flash_program.h"
void main(void){
char temp;
PTADD=0XFF;
INIT_EEPROM(); //初始化Flash控制寄存器。
do{
EEPROM_WRITE_DATA(88,0,0); //寫入一個位元組。
temp=EEPROM_READ_DATA(0,0); //讀取一個位元組
}while(temp!=88); //若寫入失敗則再次寫入
PTAD_PTAD0=1;
do{
EEPROM_ERASE();
}while(EEPROM_READ_DATA(0,0)!=0xff); //擦除Flash
PTAD_PTAD1=1;
for(;;)__RESET_WATCHDOG(); //死循環
}
10. 飛思卡爾燒寫器連接不是上是什麼原因
當初我也碰到這樣的情況,你先檢查看看是不是你的硬體的下載線斷了或者沒有連接上,或者這四根線接反了。一切正常的話,燒寫器上的兩個LED燈會亮的。