uint8_t sdmmc_readSector(uint32_t pSectorNum, char* pOutput) { SET_CS(); // Send command 17 (READ_SINGLE_BLOCK) if (sdmmc_writeCommand(SDMMC_READ_SINGLE_BLOCK, SECTOR_TO_BYTE(pSectorNum), SDMMC_DEFAULT_CRC) != 0) { CLEAR_CS(); return FALSE; } uint8_t response = 0; uint8_t retry = 0; // Wait for start-byte while(response != 0xFE) { response = spi_readByte(); if (retry++ == 0xFF) { CLEAR_CS(); return FALSE; } } // Read the block for (uint16_t i = 0; i < fBlockLength; i++) { pOutput[i] = spi_readByte(); } // Ignore the CRC checksum spi_readByte(); spi_readByte(); CLEAR_CS(); return TRUE; }
uint8_t sdmmc_writeSector(uint32_t pSectorNum, char* pInput) { SET_CS(); // Send command 24 (WRITE_BLOCK) if (sdmmc_writeCommand(SDMMC_WRITE_BLOCK, SECTOR_TO_BYTE(pSectorNum), SDMMC_DEFAULT_CRC) != 0) { CLEAR_CS(); return FALSE; } // Send some dummy clocks for(uint8_t i = 0; i < 100; i++) { spi_readByte(); } // Send start-byte spi_writeByte(0xFE); // Send data for(uint16_t i = 0; i < fBlockLength; i++) { spi_writeByte(pInput[i]); } // Send dummy CRC checksum (won't be checked in SPI mode) spi_writeByte(0xFF); spi_writeByte(0xFF); // Get response if ((spi_readByte() & 0x1F) != 0x05) { CLEAR_CS(); return FALSE; } // Wait until memory card is ready for new commands while (spi_readByte() != 0xFF) { // burn energy } CLEAR_CS(); return TRUE; }
static void mpu6000AccRead(int16_t *accData) { //uint8_t buf[6]; //SPI1_Read_Buf( MPU_RA_ACCEL_XOUT_H, 6, buf); uint8_t buf[6]; uint8_t i; MPU_ON; spi_writeByte(MPU_RA_ACCEL_XOUT_H | 0x80); for (i = 0; i < 6; i++) buf[i] = spi_readByte(); MPU_OFF; accData[0] = (int16_t)((buf[0] << 8) | buf[1]) / 8; accData[1] = (int16_t)((buf[2] << 8) | buf[3]) / 8; accData[2] = (int16_t)((buf[4] << 8) | buf[5]) / 8; }
static void mpu6000GyroRead(int16_t *gyroData) { uint8_t buf[6]; uint8_t i; MPU_ON; spi_writeByte(MPU_RA_GYRO_XOUT_H | 0x80); //SPI1_Read_Buf(MPU_RA_GYRO_XOUT_H, 6, buf); for (i = 0; i < 6; i++) buf[i] = spi_readByte(); MPU_OFF; gyroData[0] = (int16_t)((buf[0] << 8) | buf[1]) / 4; gyroData[1] = (int16_t)((buf[2] << 8) | buf[3]) / 4; gyroData[2] = (int16_t)((buf[4] << 8) | buf[5]) / 4; }
uint8_t sdmmc_writeCommand(uint8_t pCommand, uint32_t pArgument, uint8_t pCrc) { // The command is composed out of 6 Byte: // Byte 1: 0b01xxxxxx where xx = pCommand // Byte 2-5: pArgument // Byte 6: 0byyyyyyy1 where yy = CRC7 (ignored when card is in SPI mode) // Make sure that bits 7 and 6 of pCommand are 0 and 1 pCommand &= ~(1 << 7); pCommand |= (1 << 6); // Calculate CRC7 (// TODO //, currently precalculated values) // Bit 0 of the checksum byte has to be set pCrc |= 1; // Send some dummy clock signals CLEAR_CS(); spi_writeByte(0xFF); SET_CS(); // Send the data spi_writeByte(pCommand); spi_writeByte((uint8_t)((pArgument & 0xFF000000) >> 24)); spi_writeByte((uint8_t)((pArgument & 0x00FF0000) >> 16)); spi_writeByte((uint8_t)((pArgument & 0x0000FF00) >> 8)); spi_writeByte((uint8_t)(pArgument & 0x000000FF)); spi_writeByte(pCrc); // Get a response uint8_t result = 0xFF; uint8_t retry = 0; while(result == 0xFF) { result = spi_readByte(); if (retry++ == 0xFF) { result = 0; break; } } return result; }
void main() { P6DIR|=BIT1;//发光二极管 P6OUT|=BIT1; P1DIR|=BIT0;//给fpga的信号 P1OUT&=~BIT0; WDTCTL = WDTPW + WDTHOLD; //关闭看门狗 Init_CLK(); Ini_Lcd(); Init_IO(); Init_LDC1000(); Port_init(); delay_ms(100); //延时100ms while(1) { Key_Scan(); //键盘扫描,看是否有按键按下 if(key!=0xff) //如果有按键按下,则显示该按键键值1~4 { { switch(key) { case 1: LED8 = 0xFC; arange=key1;break; //给不同的键赋键值,键值1,亮2个LED灯 case 2: LED8 = 0xF3;arange=key2;break; //给不同的键赋键值,键值2,亮2个LED灯 case 3: LED8 = 0xCF;arange=key3;break; //给不同的键赋键值,键值3,亮2个LED灯 case 4: LED8 = 0x3F;arange=key4;break; //给不同的键赋键值,键值4,亮2个LED灯 } } } else { //LED=key; //没有按键的时候显示上次的键值 } proximtyData[0] = spi_readByte(LDC1000_CMD_PROXLSB); proximtyData[1] = spi_readByte(LDC1000_CMD_PROXMSB); frequencyData[0] = spi_readByte(LDC1000_CMD_FREQCTRLSB); frequencyData[1] = spi_readByte(LDC1000_CMD_FREQCTRLSB+1); frequencyData[2] = spi_readByte(LDC1000_CMD_FREQCTRLSB+2); proximtyDataMAX = ((unsigned char) proximtyData[1]<<8) + proximtyData [0]; frequencyDataMAX =((unsigned char)frequencyData[1]<<8) + frequencyData[0]; disNum(proximtyDataMAX%10+0x30,0x86); disNum(proximtyDataMAX/10%10+0x30,0x85); disNum(proximtyDataMAX/100%10+0x30,0x84); disNum(proximtyDataMAX/1000%10+0x30,0x83); disNum(proximtyDataMAX/10000%10+0x30,0x82); a = spi_readByte(LDC1000_CMD_REVID); if(proximtyDataMAX>arange) { P6OUT&=~BIT1;//灯亮 P1OUT|=BIT0;//给fpga高电平,表示发现硬币 } else { P6OUT|=BIT1; P1OUT&=~BIT0; } _NOP(); } }
bool mpu6000Detect(sensor_t * acc, sensor_t * gyro, uint16_t lpf, uint8_t *scale) { // bool ack; uint8_t sig;//, rev //uint8_t tmp[6]; delay(35); // datasheet page 13 says 30ms. other stuff could have been running meanwhile. but we'll be safe //sig = SPI1_Read( MPU_RA_WHO_AM_I); MPU_ON; spi_writeByte(MPU_RA_WHO_AM_I | 0x80); // Address with high bit set = Read operation sig = spi_readByte(); MPU_OFF; // So like, MPU6xxx has a "WHO_AM_I" register, that is used to verify the identity of the device. // The contents of WHO_AM_I are the upper 6 bits of the MPU-60X0’s 7-bit I2C address. // The least significant bit of the MPU-60X0’s I2C address is determined by the value of the AD0 pin. (we know that already). // But here's the best part: The value of the AD0 pin is not reflected in this register. if (sig !=0x68) //0x7e) return false; /*/determine product ID and accel revision SPI1_Read(int16_t *acc_tmp); rev = ((acc_tmp[5] & 0x01) << 2) | ((acc_tmp[3] & 0x01) << 1) | (acc_tmp[1] & 0x01); if (rev) { // Congrats, these parts are better. if (rev == 1) { mpuAccelHalf = 1; } else if (rev == 2) { mpuAccelHalf = 0; } else { failureMode(5); } } else { sig = SPI1_Read( MPU_RA_PRODUCT_ID, 1, &sig); rev = sig & 0x0F; if (!rev) { failureMode(5); } else if (rev == 4) { mpuAccelHalf = 1; } else { mpuAccelHalf = 0; } }*/ acc->init = mpu6000AccInit; acc->read = mpu6000AccRead; acc->align = mpu6000AccAlign; gyro->init = mpu6000GyroInit; gyro->read = mpu6000GyroRead; gyro->align = mpu6000GyroAlign; gyro->scale = (((32767.0f / 16.4f) * M_PI) / ((32767.0f / 4.0f) * 180.0f * 1000000.0f)); // give halfacc (old revision) back to system if (scale) *scale = mpuAccelHalf; // default lpf is 42Hz switch (lpf) { case 256: mpuLowPassFilter = MPU6000_LPF_256HZ; break; case 188: mpuLowPassFilter = MPU6000_LPF_188HZ; break; case 98: mpuLowPassFilter = MPU6000_LPF_98HZ; break; default: case 42: mpuLowPassFilter = MPU6000_LPF_42HZ; break; case 20: mpuLowPassFilter = MPU6000_LPF_20HZ; break; case 10: mpuLowPassFilter = MPU6000_LPF_10HZ; break; case 5: mpuLowPassFilter = MPU6000_LPF_5HZ; break; } return true; }