在仿真的时候都没问题,但是烧入芯片后串口没反应,芯片和串口都测试过没问题,希望各位高手给解答下,代码如下:
#include <reg51.h>
#include "string.h"
#define F_CPU 11059200//18432000
void delay(unsigned int time)
{
while(time--);
}
void UART_Init()
{
EA=0; //暂时关闭中断
PCON|=0x80; //PCON的最高位SMOD=1时波特率加倍
SCON = 0x50; //串行传输方式1,允许接收,开串行中断
TMOD = 0x20; //定时器方式1,16位计时
TL1 = TH1 = 0xfd; //11.0592M晶振时,0xf4为2400,0xfa为4800,0xfd为9600
// TL1 = TH1 = 0xf6; //18.432M晶振时,0xf6为9600
TR1=1; //启动定时器1
EA=1; //允许中断
}
void UART_Send_Byte(unsigned char mydata)
{
mydata = mydata;
ES=0;
TI=0;
SBUF=mydata;
while(!TI);
TI=0;
ES=1;
}
void uart_putc_hex(unsigned char b)
{
if((b >> 4) < 0x0a)
UART_Send_Byte((b >> 4) + '0');
else
UART_Send_Byte((b >> 4) - 0x0a + 'a');
if((b & 0x0f) < 0x0a)
UART_Send_Byte((b & 0x0f) + '0');
else
UART_Send_Byte((b & 0x0f) - 0x0a + 'a');
}
void UART_Send_Enter()
{
UART_Send_Byte(0x0d);
UART_Send_Byte(0x0a);
}
void uart_puts_p(char *s)
{
int len=strlen(s)-1;
int i;
for(i=0;i<len;i++)
{
UART_Send_Byte(s[i]);
}
if(s[i]=='\n')
{
UART_Send_Enter();
}
else
{
UART_Send_Byte(s[i]);
}
}
sbit SD_SCL=P3^5; //SD卡同步时钟 输入,C51的15脚
sbit SD_SI =P3^6; //SD卡同步数据 输入,C51的16脚
sbit SD_CS =P3^7; //SD卡片选 输入 C51的17脚
sbit SD_SO =P2^0; //SD卡同步数据 输出, C51的21脚
sbit sda_1161 =P1^3;
#define SD_RAW_WRITE_SUPPORT 1 // 写操作支持位
#define SD_RAW_WRITE_BUFFERING 0 // 支持写缓冲区
#define SD_RAW_SAVE_RAM 0 // 静态RAM缓存
#define SD_RAW_SDHC 1 // 默认支持SDHC卡
#define configure_pin_mosi()
#define configure_pin_sck()
#define configure_pin_ss()
#define configure_pin_miso()
#define configure_pin_available()
#define configure_pin_locked()
#define get_pin_available() 0
#define get_pin_locked() 1
#define select_card() SD_CS = 0// 成立
#define unselect_card() SD_CS = 1// 成立
#define offset_t double
#define SD_RAW_FORMAT_HARDDISK 0
#define SD_RAW_FORMAT_SUPERFLOPPY 1
#define SD_RAW_FORMAT_UNIVERSAL 2
#define SD_RAW_FORMAT_UNKNOWN 3
/* CMD0: response R1 */
#define CMD_GO_IDLE_STATE 0x00
/* CMD1: response R1 */
#define CMD_SEND_OP_COND 0x01
/* CMD8: response R7 */
#define CMD_SEND_IF_COND 0x08
/* CMD9: response R1 */
#define CMD_SEND_CSD 0x09
/* CMD10: response R1 */
#define CMD_SEND_CID 0x0a
/* CMD12: response R1 */
#define CMD_STOP_TRANSMISSION 0x0c
/* CMD13: response R2 */
#define CMD_SEND_STATUS 0x0d
/* CMD16: arg0[31:0]: block length, response R1 */
#define CMD_SET_BLOCKLEN 0x10
/* CMD17: arg0[31:0]: data address, response R1 */
#define CMD_READ_SINGLE_BLOCK 0x11
/* CMD18: arg0[31:0]: data address, response R1 */
#define CMD_READ_MULTIPLE_BLOCK 0x12
/* CMD24: arg0[31:0]: data address, response R1 */
#define CMD_WRITE_SINGLE_BLOCK 0x18
/* CMD25: arg0[31:0]: data address, response R1 */
#define CMD_WRITE_MULTIPLE_BLOCK 0x19
/* CMD27: response R1 */
#define CMD_PROGRAM_CSD 0x1b
/* CMD28: arg0[31:0]: data address, response R1b */
#define CMD_SET_WRITE_PROT 0x1c
/* CMD29: arg0[31:0]: data address, response R1b */
#define CMD_CLR_WRITE_PROT 0x1d
/* CMD30: arg0[31:0]: write protect data address, response R1 */
#define CMD_SEND_WRITE_PROT 0x1e
/* CMD32: arg0[31:0]: data address, response R1 */
#define CMD_TAG_SECTOR_START 0x20
/* CMD33: arg0[31:0]: data address, response R1 */
#define CMD_TAG_SECTOR_END 0x21
/* CMD34: arg0[31:0]: data address, response R1 */
#define CMD_UNTAG_SECTOR 0x22
/* CMD35: arg0[31:0]: data address, response R1 */
#define CMD_TAG_ERASE_GROUP_START 0x23
/* CMD36: arg0[31:0]: data address, response R1 */
#define CMD_TAG_ERASE_GROUP_END 0x24
/* CMD37: arg0[31:0]: data address, response R1 */
#define CMD_UNTAG_ERASE_GROUP 0x25
/* CMD38: arg0[31:0]: stuff bits, response R1b */
#define CMD_ERASE 0x26
/* ACMD41: arg0[31:0]: OCR contents, response R1 */
#define CMD_SD_SEND_OP_COND 0x29
/* CMD42: arg0[31:0]: stuff bits, response R1b */
#define CMD_LOCK_UNLOCK 0x2a
/* CMD55: arg0[31:0]: stuff bits, response R1 */
#define CMD_APP 0x37
/* CMD58: arg0[31:0]: stuff bits, response R3 */
#define CMD_READ_OCR 0x3a
/* CMD59: arg0[31:1]: stuff bits, arg0[0:0]: crc option, response R1 */
#define CMD_CRC_ON_OFF 0x3b
#define R1_IDLE_STATE 0
#define R1_ERASE_RESET 1
#define R1_ILL_COMMAND 2
#define R1_COM_CRC_ERR 3
#define R1_ERASE_SEQ_ERR 4
#define R1_ADDR_ERR 5
#define R1_PARAM_ERR 6
#define R2_CARD_LOCKED 0
#define R2_WP_ERASE_SKIP 1
#define R2_ERR 2
#define R2_CARD_ERR 3
#define R2_CARD_ECC_FAIL 4
#define R2_WP_VIOLATION 5
#define R2_INVAL_ERASE 6
#define R2_OUT_OF_RANGE 7
#define R2_CSD_OVERWRITE 7
#define R2_IDLE_STATE (R1_IDLE_STATE + 8)
#define R2_ERASE_RESET (R1_ERASE_RESET + 8)
#define R2_ILL_COMMAND (R1_ILL_COMMAND + 8)
#define R2_COM_CRC_ERR (R1_COM_CRC_ERR + 8)
#define R2_ERASE_SEQ_ERR (R1_ERASE_SEQ_ERR + 8)
#define R2_ADDR_ERR (R1_ADDR_ERR + 8)
#define R2_PARAM_ERR (R1_PARAM_ERR + 8)
#define R3_OCR_MASK (0xffffffffUL)
#define R3_IDLE_STATE (R1_IDLE_STATE + 32)
#define R3_ERASE_RESET (R1_ERASE_RESET + 32)
#define R3_ILL_COMMAND (R1_ILL_COMMAND + 32)
#define R3_COM_CRC_ERR (R1_COM_CRC_ERR + 32)
#define R3_ERASE_SEQ_ERR (R1_ERASE_SEQ_ERR + 32)
#define R3_ADDR_ERR (R1_ADDR_ERR + 32)
#define R3_PARAM_ERR (R1_PARAM_ERR + 32)
#define DR_STATUS_MASK 0x0e
#define DR_STATUS_ACCEPTED 0x05
#define DR_STATUS_CRC_ERR 0x0a
#define DR_STATUS_WRITE_ERR 0x0c
#define SD_RAW_SPEC_1 0 // 第1种类型卡
#define SD_RAW_SPEC_2 1 // 第2种类型卡
#define SD_RAW_SPEC_SDHC 2// SDHC类型卡
static unsigned char xdata raw_block[512];
static offset_t raw_block_address;
static unsigned char sd_raw_card_type;
volatile unsigned int DELAY_TIME = 1000;
void SpiSpeedLow62KHZ(void)
{
DELAY_TIME = 20;
}
void SpiSpeedHigh4MHZ(void)
{
DELAY_TIME = 0;
}
unsigned char bdata _dat;
sbit _dat7=_dat^7;
sbit _dat6=_dat^6;
sbit _dat5=_dat^5;
sbit _dat4=_dat^4;
sbit _dat3=_dat^3;
sbit _dat2=_dat^2;
sbit _dat1=_dat^1;
sbit _dat0=_dat^0;
void sd_raw_send_byte(unsigned char x)
{
_dat=x;
SD_SI=_dat7;
SD_SCL=0;
delay(DELAY_TIME);
SD_SCL=1;
delay(DELAY_TIME);
SD_SI=_dat6;
SD_SCL=0;
delay(DELAY_TIME);
SD_SCL=1;
delay(DELAY_TIME);
SD_SI=_dat5;
SD_SCL=0;
delay(DELAY_TIME);
SD_SCL=1;
delay(DELAY_TIME);
SD_SI=_dat4;
SD_SCL=0;
delay(DELAY_TIME);
SD_SCL=1;
delay(DELAY_TIME);
SD_SI=_dat3;
SD_SCL=0;
delay(DELAY_TIME);
SD_SCL=1;
delay(DELAY_TIME);
SD_SI=_dat2;
SD_SCL=0;
delay(DELAY_TIME);
SD_SCL=1;
delay(DELAY_TIME);
SD_SI=_dat1;
SD_SCL=0;
delay(DELAY_TIME);
SD_SCL=1;
delay(DELAY_TIME);
SD_SI=_dat0;
SD_SCL=0;
delay(DELAY_TIME);
SD_SCL=1;
delay(DELAY_TIME);
}
unsigned char sd_raw_rec_byte(void)
{
SD_SO=1;
SD_SCL=1;
delay(DELAY_TIME);
SD_SCL=0;
delay(DELAY_TIME);
_dat7=SD_SO;
SD_SCL=1;
delay(DELAY_TIME);
SD_SCL=0;
delay(DELAY_TIME);
_dat6=SD_SO;
SD_SCL=1;
delay(DELAY_TIME);
SD_SCL=0;
delay(DELAY_TIME);
_dat5=SD_SO;
SD_SCL=1;
delay(DELAY_TIME);
SD_SCL=0;
delay(DELAY_TIME);
_dat4=SD_SO;
SD_SCL=1;
delay(DELAY_TIME);
SD_SCL=0;
delay(DELAY_TIME);
_dat3=SD_SO;
SD_SCL=1;
delay(DELAY_TIME);
SD_SCL=0;
delay(DELAY_TIME);
_dat2=SD_SO;
SD_SCL=1;
delay(DELAY_TIME);
SD_SCL=0;
delay(DELAY_TIME);
_dat1=SD_SO;
SD_SCL=1;
delay(DELAY_TIME);
SD_SCL=0;
delay(DELAY_TIME);
_dat0=SD_SO;
return (_dat);
}
unsigned char sd_raw_send_command(unsigned char command, unsigned long arg)
{
unsigned char response;
unsigned char i;
sd_raw_rec_byte();
sd_raw_send_byte(0x40 | command);
sd_raw_send_byte((arg >> 24) & 0xff);
sd_raw_send_byte((arg >> 16) & 0xff);
sd_raw_send_byte((arg >> 8) & 0xff);
sd_raw_send_byte((arg >> 0) & 0xff);
switch(command)
{
case CMD_GO_IDLE_STATE:
sd_raw_send_byte(0x95);
break;
case CMD_SEND_IF_COND:
sd_raw_send_byte(0x87);
break;
default:
sd_raw_send_byte(0xff);
break;
}
for(i = 0; i < 10; ++i)
{
response = sd_raw_rec_byte();
if(response != 0xff)
break;
}
return response;
}
#define uint8_t unsigned char
#define uint16_t unsigned int
#define uintptr_t unsigned int
uint8_t sd_raw_read(offset_t offset, uint8_t* buffer, uintptr_t length)
{
offset_t block_address;
uint16_t block_offset;
uint16_t read_length;
uint8_t *cache;
uint16_t i;
while(length > 0)
{
block_offset = (uint16_t)offset & 0x01ff;
block_address = offset - block_offset;
read_length = 512 - block_offset;
if(read_length > length)
{
read_length = length;
}
if(block_address != raw_block_address)
{
select_card();
#if SD_RAW_SDHC
if(sd_raw_send_command(CMD_READ_SINGLE_BLOCK, (sd_raw_card_type & (1 << SD_RAW_SPEC_SDHC) ? block_address / 512 : block_address)))
#else
if(sd_raw_send_command(CMD_READ_SINGLE_BLOCK, block_address))
#endif
{
unselect_card();
return 0;
}
/* wait for data block (start byte 0xfe) */
while(sd_raw_rec_byte() != 0xfe);
/* read byte block */
cache = raw_block;
for(i = 0; i < 512; ++i)
*cache++ = sd_raw_rec_byte();
raw_block_address = block_address;
memcpy(buffer, raw_block + block_offset, read_length);
buffer += read_length;
/* read crc16 */
sd_raw_rec_byte();
sd_raw_rec_byte();
/* deaddress card */
unselect_card();
/* let card some time to finish */
sd_raw_rec_byte();
}
else
{
/* use cached data */
memcpy(buffer, raw_block + block_offset, read_length);
buffer += read_length;
}
length -= read_length;
offset += read_length;
}
return 1;
}
unsigned char sd_raw_init()
{
unsigned char i;
unsigned char response;
unsigned int i2;
unsigned int i3;
configure_pin_mosi(); // 输出
configure_pin_sck(); // 输出
configure_pin_ss(); // 输出
configure_pin_miso(); // 输入
unselect_card(); // 禁止cs
/* initialize SPI with lowest frequency; max. 400kHz during identification mode of card
初始化为spi模式,注意现在需在400kHZ频率以内 */
SpiSpeedLow62KHZ();
/* initialization procedure */
sd_raw_card_type = 0; // 卡类型变量复位
/* card needs 74 cycles minimum to start up */
for(i = 0; i < 0x0f; ++i) // 74个前期时钟
{
/* wait 8 clock cycles */
sd_raw_send_byte(0xff); // spi总线发送oxff
}
/* address card */
select_card(); // 使能sd卡
/* reset card */
for(i2 = 0; ; ++i2)
{
response = sd_raw_send_command(CMD_GO_IDLE_STATE, 0);
// 复位置于spi模式
if(response == (1 << R1_IDLE_STATE))
break;
uart_putc_hex(response);
UART_Send_Enter();
if(i2 == 0x1ff)
{
unselect_card(); // 禁止卡
return 0;
}
}
#if SD_RAW_SDHC
/* check for version of SD card specification */
response = sd_raw_send_command(CMD_SEND_IF_COND, 0x100 /* 2.7V - 3.6V */ | 0xaa /* test pattern */);
if((response & (1 << R1_ILL_COMMAND)) == 0)
{
sd_raw_rec_byte();
sd_raw_rec_byte();
if((sd_raw_rec_byte() & 0x01) == 0)
return 0; /* card operation voltage range doesn't match */
if(sd_raw_rec_byte() != 0xaa)
return 0; /* wrong test pattern */
/* card conforms to SD 2 card specification */
sd_raw_card_type |= (1 << SD_RAW_SPEC_2);
}
else
#endif
{
/* determine SD/MMC card type */
sd_raw_send_command(CMD_APP, 0); // 0x37 判断是SD卡还是MMC卡
response = sd_raw_send_command(CMD_SD_SEND_OP_COND, 0); // 0x29
if((response & (1 << R1_ILL_COMMAND)) == 0) // 1<<2
{
/* card conforms to SD 1 card specification */
sd_raw_card_type |= (1 << SD_RAW_SPEC_1); // 为SD卡
}
else
{
/* 为 MMC card 卡*/
}
}
/* wait for card to get ready 等待SD卡忙完 */
for(i3 = 0; ; ++i3)
{
if(sd_raw_card_type & ((1 << SD_RAW_SPEC_1) | (1 << SD_RAW_SPEC_2)))
{
unsigned long arg = 0;
#if SD_RAW_SDHC
if(sd_raw_card_type & (1 << SD_RAW_SPEC_2))
arg = 0x40000000;
#endif
sd_raw_send_command(CMD_APP, 0);
response = sd_raw_send_command(CMD_SD_SEND_OP_COND, arg); // 激活卡内部初始化
}
else
{
response = sd_raw_send_command(CMD_SEND_OP_COND, 0); // 激活卡内部初始化
}
if((response & (1 << R1_IDLE_STATE)) == 0)
break;
if(i3 == 0x7fff)
{
unselect_card();
return 0;
}
}
#if SD_RAW_SDHC
if(sd_raw_card_type & (1 << SD_RAW_SPEC_2))
{
if(sd_raw_send_command(CMD_READ_OCR, 0))
{
unselect_card();
return 0;
}
if(sd_raw_rec_byte() & 0x40)
sd_raw_card_type |= (1 << SD_RAW_SPEC_SDHC);
sd_raw_rec_byte();
sd_raw_rec_byte();
sd_raw_rec_byte();
}
#endif
/* set block size to 512 bytes 设置512字节为1块 */
if(sd_raw_send_command(CMD_SET_BLOCKLEN, 512))
{
unselect_card();
return 0;
}
/* deaddress card */
unselect_card();
/* switch to highest SPI frequency possible */
// 转换spi总线到高速模式
SpiSpeedHigh4MHZ();
#if !SD_RAW_SAVE_RAM
/* the first block is likely to be accessed first, so precache it here */
// 第1个块可能首先使用,先准备好缓冲
raw_block_address = (offset_t) -1;
if(!sd_raw_read(0, raw_block, sizeof(raw_block)))
return 0;
#endif
return 1;
}
uint8_t sd_raw_write(offset_t offset, const uint8_t* buffer, uintptr_t length)
{
offset_t block_address;
uint16_t block_offset;
uint16_t write_length;
uint8_t *cache;
uint16_t i;
while(length > 0)
{
block_offset = (uint16_t)offset & 0x01ff;
block_address = offset - block_offset;
write_length = 512 - block_offset; /* write up to block border */
if(write_length > length)
write_length = length;
if(block_address != raw_block_address)
{
if(block_offset || write_length < 512)
{
if(!sd_raw_read(block_address, raw_block, sizeof(raw_block)))
return 0;
}
raw_block_address = block_address;
}
if(buffer != raw_block)
{
memcpy(raw_block + block_offset, buffer, write_length);
}
/* address card */
select_card();
/* send single block request */
#if SD_RAW_SDHC
if(sd_raw_send_command(CMD_WRITE_SINGLE_BLOCK, (sd_raw_card_type & (1 << SD_RAW_SPEC_SDHC) ? block_address / 512 : block_address)))
#else
if(sd_raw_send_command(CMD_WRITE_SINGLE_BLOCK, block_address))
#endif
{
unselect_card();
return 0;
}
sd_raw_send_byte(0xfe);
cache = raw_block;
for(i = 0; i < 512; ++i)
sd_raw_send_byte(*cache++);
sd_raw_send_byte(0xff);
sd_raw_send_byte(0xff);
while(sd_raw_rec_byte() != 0xff);
sd_raw_rec_byte();
unselect_card();
buffer += write_length;
offset += write_length;
length -= write_length;
}
return 1;
}
// sfr STC89X51_AUXR = 0x8E;
#define ADDR 0x808001
// unsigned char tempfor = 1;
uint8_t temp[20];
void DelayMs(unsigned int temp)
{
unsigned char i;
while(temp--)
for(i = 0;i<125;i++);
{ sda_1161 = 1;
sda_1161 = 0; }
}
void main(void)
{
uint8_t flag= 0xff;
uint16_t i;
DelayMs(4000);
// STC89X51_AUXR &= 0x01; // 启动STC内部xdata的RAM
UART_Init();
uart_puts_p("P89V51 uart OK\n");
while(1)
{
if(!sd_raw_init())
{
uart_puts_p("SDHC initialization failed\n");
while(1);
}
uart_puts_p("OK\n");
for(i=0;i<sizeof(temp);i++)
{
temp[i] = i;
}
flag = sd_raw_write(0x808001, temp, sizeof(temp));
uart_puts_p("SDHC Write flag is : ");
uart_putc_hex(flag);
UART_Send_Enter();
uart_puts_p("SDHC Write OK \n");
for(i=0;i<sizeof(temp);i++)
{
temp[i] = 0;
}
flag = sd_raw_read(0x808001,temp,sizeof(temp));
uart_puts_p("SDHC Read flag is : ");
uart_putc_hex(flag);
UART_Send_Enter();
for(i=0;i<sizeof(temp);i++)
{
uart_putc_hex(temp[i]);
uart_puts_p(",");
}
UART_Send_Enter();
UART_Send_Enter();
while(1);
}
} |
|