Вт окт 30, 2018 06:10:12
DDRB |= (1<<PINB1); //ножка fast шим
PORTB = 0;
TCCR1A = (1<<COM1A1) | (0<<COM1A0) | (1<<WGM11) | (0<<WGM10);
TCCR1B = (1<<WGM13) | (1<<WGM12) | (0<<CS11) | (0<<CS12) | (1<<CS10);
ICR1 = 0xFFFF; // модуль счета - максимум
ADCSRA |= (1<<ADEN) // Разрешение использования АЦП
|(1<<ADSC)//Запуск преобразования
|(1<<ADFR)//Непрерывный режим работы АЦП
|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0)//Делитель 128 = 64 кГц
|(1<<ADIE);//Разрешение прерывания от АЦП
ADMUX |= (1<<REFS1)|(1<<REFS0); //Внутренний Источник ОН 2,56в, вход ADC0
ISR(ADC_vect)
{
low_adc = ADCL;
high_adc = ADCH;//Верхняя часть регистра ADC должна быть считана последней, иначе не продолжится преобразование
adc_value= (high_adc<<8)|low_adc;
OCR1A = 0xFFFF - (adc_value*64);
}
TIMSK |= (1<<TOIE2); // Разрешаем прерывание по переполнению
TCCR2 |= (1<<CS22)|(1<<CS20); // Предделитель на 128
DDRB&=~(1<<DDRB0); //Настраиваем ножку PB0 в режим входа
PORTB|=(1<<PORTB0); //Устанавливаем pull-up режим ножки PB0
TCCR0 |= (1<<CS02)|(1<<CS00);
TIMSK |= (1<<TOIE0);
Вт окт 30, 2018 08:36:17
если б я не был таким ленивым, я бы задействовал для подстройки часов FM-радио, а именно RDS.MrJunior писал(а):Я понимаю что часы со временем будут либо убегать либо отставать, и это будет зависеть от окружающей среды кварца. Чем теплее скорее всего тем часы сильнее будут убегать вперед ( это я предполагаю) , чем холоднее наоборот. Поэтому хотелось бы связаться с интернетом, но...
Вт окт 30, 2018 10:36:17
Про VisualGDB не слышали? https://visualgdb.com/?features=embeddedMrJunior писал(а):Выбрал AVR, только потому, что Atmel studio базируется на visual studio
Вт окт 30, 2018 11:35:07
Вт окт 30, 2018 12:14:59
ну а аргументы будут посерьезнее, чем сказано?AndTer писал(а):Приехали... РДС и ЖПС отттуда же...
Вт окт 30, 2018 13:16:15
void I2C_Init(void)
{
TWBR=0x20; //скорость передачи (при 8 мГц получается 100 кГц) надо настроить ?
}
void I2C_Start(void)
{
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
while(!(TWCR&(1<<TWINT)));//подождем пока установится TWIN
}
void I2C_Stop(void)
{
TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN);
}
int I2C_WriteByte(unsigned char c)
{
TWDR=c;//запишем байт в регистр данных
TWCR = (1<<TWINT)|(1<<TWEN);//включим передачу данных
while(!(TWCR&(1<<TWINT)));//подождем пока установится TWIN
//if ((TWSR & 0xF8) != I2C_MT_DATA_ASK) return 1; else
return 0;
}
unsigned char I2C_ReadByte(void)
{
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);//включим прием данных
while(!(TWCR & (1<<TWINT)));//подождем пока установится TWIN
//if ((TWSR & 0xF8) != I2C_MR_DATA_ASK) return 1; else
return TWDR;
}
unsigned char I2C_ReadLastByte(void)
{
TWCR = (1<<TWINT)|(1<<TWEN);//включим прием данных
while(!(TWCR&(1<<TWINT)));//подождем пока установится TWIN
//if ((TWSR & 0xF8) != I2C_MR_DATA_NASK) return 1; else
return TWDR;
}
void setRegister(byte reg, const word value) {
I2C_Start();
I2C_WriteByte(RDA5807M_I2C_ADDR_RANDOM); //Wire.beginTransmission(RDA5807M_I2C_ADDR_RANDOM);
I2C_WriteByte(reg); //Wire.write(reg);
I2C_WriteByte(value >> 8); //Wire.write(highByte(value));
I2C_WriteByte(value & 0xFF); //Wire.write(lowByte(value));
I2C_Stop(); //Wire.endTransmission(true);
}
word getRegister(byte reg) {
word result;
I2C_Start();
I2C_WriteByte(RDA5807M_I2C_ADDR_RANDOM); //Wire.beginTransmission(RDA5807M_I2C_ADDR_RANDOM);
I2C_WriteByte(reg); ///Wire.write(reg);
//Wire.endTransmission(false);
//Wire.requestFrom(RDA5807M_I2C_ADDR_RANDOM, 2, true);
//Don't let gcc play games on us, enforce order of execution.
result = (word)I2C_ReadByte() << 8;//result = (word)Wire.read() << 8;
result |= I2C_ReadLastByte();//result |= Wire.read();
I2C_Stop();
return result;
}
typedef unsigned int word;
typedef unsigned char byte;
#include "main.h"
#ifndef RDA5807M_H_
#define RDA5807M_H_
//Define RDA5807M I2C Addresses
#define RDA5807M_I2C_ADDR_SEQRDA (0x20 >> 1)
#define RDA5807M_I2C_ADDR_RANDOM (0x22 >> 1)
#define RDA5807M_I2C_ADDR_SEQTEA (0xC0 >> 1)
typedef unsigned int word;
typedef unsigned char byte;
//Register file origins for sequential mode
#define RDA5807M_FIRST_REGISTER_WRITE 0x02
#define RDA5807M_FIRST_REGISTER_READ 0x0A
#define RDA5807M_LAST_REGISTER 0x3A
//Register addresses
#define RDA5807M_REG_CHIPID 0x00
#define RDA5807M_REG_CONFIG 0x02
#define RDA5807M_REG_TUNING 0x03
#define RDA5807M_REG_GPIO 0x04
#define RDA5807M_REG_VOLUME 0x05
#define RDA5807M_REG_I2S 0x06
#define RDA5807M_REG_BLEND 0x07
#define RDA5807M_REG_FREQ 0x08
#define RDA5807M_REG_STATUS 0x0A
#define RDA5807M_REG_RSSI 0x0B
#define RDA5807M_REG_RDSA 0x0C
#define RDA5807M_REG_RDSB 0x0D
#define RDA5807M_REG_RDSC 0x0E
#define RDA5807M_REG_RDSD 0x0F
#define RDA5800_REG_LNA 0x10
#define RDA5807M_REG_SEEK 0x20
//Status bits (from the chip)
#define RDA5807M_STATUS_RDSR 0x8000
#define RDA5807M_STATUS_STC 0x4000
#define RDA5807M_STATUS_SF 0x2000
#define RDA5807M_STATUS_RDSS 0x1000
#define RDA5807M_STATUS_BLKE 0x0800
#define RDA5807M_STATUS_ST 0x0400
#define RDA5800_STATUS_ST 0x0100
//Flag bits (to the chip)
#define RDA5807M_FLG_DHIZ 0x8000
#define RDA5807M_FLG_DMUTE 0x4000
#define RDA5807M_FLG_MONO 0x2000
#define RDA5807M_FLG_BASS 0x1000
#define RDA5807M_FLG_RCLKNOCAL 0x0800
#define RDA5807M_FLG_RCLKDIRECT 0x0400
#define RDA5807M_FLG_SEEKUP 0x0200
#define RDA5807M_FLG_SEEK 0x0100
#define RDA5807M_FLG_SKMODE 0x0080
#define RDA5807M_FLG_RDS 0x0008
#define RDA5807M_FLG_NEW 0x0004
#define RDA5807M_FLG_RESET 0x0002
#define RDA5807M_FLG_ENABLE 0x0001
#define RDA5807M_FLG_DIRECT 0x0020
#define RDA5807M_FLG_TUNE 0x0010
#define RDA5807M_FLG_DE 0x0800
#define RDA5807M_FLG_SOFTMUTE 0x0200
#define RDA5807M_FLG_AFCD 0x0100
#define RDA5807P_FLG_INTMODE 0x8000
#define RDA5807M_FLG_EASTBAND65M 0x0200
#define RDA5807M_FLG_SOFTBLEND 0x0002
#define RDA5807M_FLG_FREQMODE 0x0001
#define RDA5807M_FLG_FMTRUE 0x0100
#define RDA5807M_FLG_FMREADY 0x0080
#define RDA5807M_FLG_BLOCKE 0x0010
#define RDA5807P_FLG_STCIEN 0x4000
#define RDA5807P_FLG_I2S 0x0040
#define RDA5807P_FLG_I2SSLAVE 0x1000
#define RDA5807P_FLG_SWLR 0x0800
#define RDA5807P_FLG_SCLKINVERT_I 0x0400
#define RDA5807P_FLG_SIGNED 0x0200
#define RDA5807P_FLG_WSINVERT_I 0x0100
#define RDA5807P_FLG_WSINVERT_O 0x0008
#define RDA5807P_FLG_SCLKINVERT_O 0x0004
#define RDA5807P_FLG_DELAY_L 0x0002
#define RDA5807P_FLG_DELAY_R 0x0001
#define RDA5800_FLG_SPACE_200K 0x0001
#define RDA5800_FLG_SPACE_50K 0x0004
#define RDA5800_FLG_BAND_JAPAN 0x0002
//Masks and constants for configuration parameters
//NOTE: the entire family, including the RDA5800, all report the same ChipID.
#define RDA5807M_CHIPID 0x58
#define RDA5807M_CLKMODE_MASK 0x0070
#define RDA5807M_CLKMODE_32K (0x0 << 4)
#define RDA5807M_CLKMODE_12M (0x1 << 4)
#define RDA5807M_CLKMODE_13M (0x2 << 4)
#define RDA5807M_CLKMODE_19M (0x3 << 4)
#define RDA5807M_CLKMODE_24M (0x5 << 4)
#define RDA5807M_CLKMODE_26M (0x6 << 4)
#define RDA5807M_CLKMODE_38M (0x7 << 4)
#define RDA5807M_CHAN_MASK 0xFFC0
#define RDA5807M_CHAN_SHIFT 6
#define RDA5807M_BAND_MASK 0x000C
#define RDA5807M_BAND_SHIFT 2
#define RDA5807M_BAND_WEST (0x0 << 2)
#define RDA5807M_BAND_JAPAN (0x1 << 2)
#define RDA5807M_BAND_WORLD (0x2 << 2)
#define RDA5807M_BAND_EAST (0x3 << 2)
#define RDA5807M_SPACE_MASK 0x0003
#define RDA5807M_SPACE_100K 0x0
#define RDA5807M_SPACE_200K 0x1
#define RDA5807M_SPACE_50K 0x2
#define RDA5807M_SPACE_25K 0x3
#define RDA5807M_SEEKTH_MASK 0x7F00
#define RDA5807M_SEEKTH_SHIFT 8
#define RDA5807M_VOLUME_MASK 0x000F
#define RDA5807M_VOLUME_SHIFT 0
#define RDA5807M_OPENMODE_MASK 0x6000
#define RDA5807M_OPENMODE_WRITE (0x3 << 13)
#define RDA5807M_SOFTBLENDTH_MASK 0x7C00
#define RDA5807M_SOFTBLENDTH_SHIFT 10
#define RDA5807M_SEEKTHOLD_MASK 0x00FC
#define RDA5807M_SEEKTHOLD_SHIFT 2
#define RDA5807M_SEEKMODE_MASK 0x7000
#define RDA5807M_SEEKMODE_OLD (0x1 << 12)
#define RDA5807M_READCHAN_MASK 0x03FF
#define RDA5807M_RSSI_MASK 0xFE00
#define RDA5807M_RSSI_SHIFT 9
#define RDA5807M_BLERA_MASK 0x000C
#define RDA5807M_BLERA_0 (0x0 << 2)
#define RDA5807M_BLERA_12 (0x1 << 2)
#define RDA5807M_BLERA_35 (0x2 << 2)
#define RDA5807M_BLERA_U (RDA5807M_BLERA_12 | RDA5807M_BLERA_35)
#define RDA5807M_BLERB_MASK 0x0003
#define RDA5807M_BLERB_0 0x0
#define RDA5807M_BLERB_12 0x1
#define RDA5807M_BLERB_35 0x2
#define RDA5807M_BLERB_U (RDA5807M_BLERB_12 | RDA5807M_BLERB_35)
#define RDA5807P_GPIO3_MASK 0x0030
#define RDA5807P_GPIO3_HIZ (0x0 << 4)
#define RDA5807P_GPIO3_ST (0x1 << 4)
#define RDA5807P_GPIO3_L (0x2 << 4)
#define RDA5807P_GPIO3_H (0x3 << 4)
#define RDA5807P_GPIO2_MASK 0x000C
#define RDA5807P_GPIO2_HIZ (0x0 << 2)
#define RDA5807P_GPIO2_INT (0x1 << 2)
#define RDA5807P_GPIO2_L (0x2 << 2)
#define RDA5807P_GPIO2_H (0x3 << 2)
#define RDA5807P_GPIO1_MASK 0x0003
#define RDA5807P_GPIO1_HIZ 0x0
#define RDA5807P_GPIO1_L 0x2
#define RDA5807P_GPIO1_H 0x3
#define RDA5807P_LNAP_MASK 0x00C0
#define RDA5807P_LNAP_NONE (0x0 << 6)
#define RDA5807P_LNAP_N (0x1 << 6)
#define RDA5807P_LNAP_P (0x2 << 6)
#define RDA5807P_LNAP_BOTH (0x3 << 6)
#define RDA5807P_LNAI_MASK 0x0030
#define RDA5807P_LNAI_1_8M (0x0 << 4)
#define RDA5807P_LNAI_2_1M (0x1 << 4)
#define RDA5807P_LNAI_2_5M (0x2 << 4)
#define RDA5807P_LNAI_3_0M (0x3 << 4)
#define RDA5807P_I2SRATE_MASK 0x00F0
#define RDA5807P_I2SRATE_8K (0x0 << 4)
#define RDA5807P_I2SRATE_11_025K (0x1 << 4)
#define RDA5807P_I2SRATE_12K (0x2 << 4)
#define RDA5807P_I2SRATE_16K (0x3 << 4)
#define RDA5807P_I2SRATE_22_05K (0x4 << 4)
#define RDA5807P_I2SRATE_24K (0x5 << 4)
#define RDA5807P_I2SRATE_32K (0x6 << 4)
#define RDA5807P_I2SRATE_44_1K (0x7 << 4)
#define RDA5807P_I2SRATE_48K (0x8 << 4)
#define RDA5800_VOLUMEDSP_MASK 0x00F0
#define RDA5800_VOLUMEDSP_SHIFT 4
#define RDA5800_LNAP_MASK 0x6000
#define RDA5800_LNAP_N (0x1 << 13)
#define RDA5800_LNAP_P (0x2 << 13)
#define RDA5800_LNAP_BOTH (0x3 << 13)
//DO NOT USE (begin) ----------
//
//One day, avr-gcc will take its role seriously and allow a way to enforce
//struct packing order, because it's a very common idiom in the embedded world
//and because the standard allows the implementation to define it.
//Until then, the beautiful structs below are nothing but an exercise in C
//calligraphy.
typedef struct __attribute__ ((__packed__)) {
uint8_t disableHiZ:1;
uint8_t disableMute:1;
uint8_t mono:1;
uint8_t bass:1;
uint8_t rClkNotAlways:1;
uint8_t rClkInput:1;
uint8_t seekUp:1;
uint8_t seek:1;
uint8_t seekMode:1;
uint8_t clkMode:3;
uint8_t rds:1;
uint8_t newDemodulation:1;
uint8_t softReset:1;
uint8_t enable:1;
union {
uint16_t channel:10;
struct {
uint8_t channel5800;
uint8_t reserved5800_1:2;
};
};
uint8_t direct:1;
uint8_t tune:1;
union {
struct {
uint8_t band:2;
uint8_t space:2;
};
struct {
uint8_t reserved5800_2:1;
uint8_t space50kHz:1;
uint8_t band5800:1;
uint8_t space5800:1;
};
};
uint8_t reserved1:1;
uint8_t stcInterruptEnable:1;
uint8_t reserved2:2;
uint8_t deEmphasis:1;
uint8_t reserved3:1;
uint8_t softMute:1;
uint8_t afcDisable:1;
uint8_t reserved4:1;
uint8_t i2s:1;
uint8_t gpio3:2;
uint8_t gpio2:2;
uint8_t gpio1:2;
uint8_t interruptMode:1;
uint8_t seekThreshold:7;
union {
struct {
uint8_t lnaPort:2;
uint8_t lnaCurrent:2;
};
uint8_t volumeDSP:4;
};
uint8_t volume:4;
uint8_t reserved5:1;
uint8_t openMode:2;
uint8_t i2sMode:1;
uint8_t wsIsRight:1;
uint8_t invertSclkInput:1;
uint8_t signedData:1;
uint8_t invertWsInput:1;
uint8_t i2sSampleRate:4;
uint8_t invertWsOutput:1;
uint8_t invertSclkOutput:1;
uint8_t delayLeft:1;
uint8_t delayRight:1;
uint8_t reserved6:1;
uint8_t softBlendThreshold:5;
uint8_t bandLimit65M:1;
uint8_t reserved7:1;
uint8_t seekThresholdOld:6;
uint8_t softBlend:1;
uint8_t frequencyMode:1;
uint16_t frequencyDirect;
} TRDA5807MRegisterFileWrite;
typedef struct __attribute__ ((__packed__)) {
uint8_t rdsReady:1;
uint8_t seekTuneComplete:1;
uint8_t seekFail:1;
uint8_t rdsSynchronized:1;
uint8_t blockEFound:1;
uint8_t stereo:1;
union {
uint16_t readChannel:10;
struct {
uint8_t reserved5800_3:1;
uint8_t stereo5800:1;
uint8_t readChannel5800;
};
};
uint8_t rssi:7;
uint8_t isStation:1;
uint8_t ready:1;
uint8_t reserved:2;
uint8_t blockE:1;
uint8_t blerA:2;
uint8_t blerB:2;
uint16_t rdsA;
uint16_t rdsB;
uint16_t rdsC;
uint16_t rdsD;
} TRDA5807MRegisterFileRead;
//DO NOT USE (end)----------
extern const word RDA5807M_BandLowerLimits[];
extern const word RDA5807M_BandHigherLimits[];
extern const byte RDA5807M_ChannelSpacings[];
/*
* Description:
* This is the constructor, it initializes internal data structures.
*/
/*
* Description:
* This is the destructor, it delegates to end().
*/
//~RDA5807M() { end(); };
/*
* Description:
* Mutes and disables the chip.
*/
void end(void);
/*
* Description:
* Initializes the RDA5807M, starts the radio and configures band
* limits.
* Parameters:
* band - The desired band limits, one of the RDA5807M_BAND_*
* constants.
*/
void begin(byte band);
/*
* Description:
* Getter and setter for single random access to registers.
* Parameters:
* reg - register to get or set, one of the RDA5807M_REG_* constants.
* value - value to set the given register to.
* Returns:
* current value of given register.
*/
void setRegister(byte reg, word value);
word getRegister(byte reg);
/*
* Description:
* Read-before-write setter for single random access to registers.
* Parameters:
* reg - register to update, one of the RDA5807M_REG_* constants.
* mask - mask of the bits that are to be updated.
* value - value to set the given register and bits to.
*/
void updateRegister(byte reg, word mask, word value) ;
/*
* Description:
* Getter and setter for bulk sequential access to registers. Gets
* always start at RDA5807M_FIRST_REGISTER_READ while sets always
* start at RDA5807M_FIRST_REGISTER_WRITE. The RDA5807M register file
* has exactly RDA5807M_LAST_REGISTER word-sized entries.
* Parameters:
* count - how many sequential registers to get/set.
* regs - will be filled with the values of the got registers or will
* be the source of the values for the set registers.
*/
void setRegisterBulk(byte count, const word regs[]);
void getRegisterBulk(byte count, word regs[]);
//DO NOT USE (begin) ----------
/*
* Description:
* Overloaded versions of the above, for use with the memory mapped
* register file structs. This is needed because Arduino and RDS5807M
* differ in endianness and so to maintain the correspondence between
* struct fields and the actual values transferred, you need to process
* the memory mapped struct byte-wise.
*/
void setRegisterBulk_memory(const TRDA5807MRegisterFileWrite *regs);
void getRegisterBulk_memory(TRDA5807MRegisterFileRead *regs);
//DO NOT USE (end) ----------
/*
* Description:
* Increase the volume by 1. If the maximum volume has been
* reached, no further increase will take place and returns false;
* otherwise true.
*/
char volumeUp(void);
/*
* Description:
* Decrease the volume by 1. If the minimum volume has been
* reached, no further decrease will take place and returns false;
* otherwise true.
* Parameters:
* alsoMute - mute the output when reaching minimum volume, in
* addition to returning false
*/
char volumeDown(char alsoMute); //false
/*
* Description:
* Commands the radio to seek up to the next valid channel.
* Parameters:
* wrap - set to true to allow the seek to wrap around the current
* band.
*/
void seekUp(char wrap); // true
/*
* Description:
* Commands the radio to seek down to the next valid channel.
* Parameters:
* wrap - set to true to allow the seek to wrap around the current
* band.
*/
void seekDown(char wrap); // true
/*
* Description:
* Mutes the audio output.
*/
void mute(void);
/*
* Description:
* Unmutes the audio output.
* Parameters:
* minVolume - set the volume to minimum value before unmuting if true,
* otherwise leave it untouched causing the chip to blast
* audio out at whatever the previous volume level was.
*/
void unMute(char minVolume); // false
/*
* Description:
* Gets the frequency the chip is currently tuned to.
* Returns:
* frequency in 10kHz units.
*/
word getFrequency(void);
/*
* Description:
* Tells the chip to tune to the given frequency if within the
* currently configured band limits and returns true, otherwise false.
* Parameters:
* frequency - the frequency to tune to, in 10kHz units.
*/
char setFrequency(word frequency);
/*
* Description:
* Retrieves the Received Signal Strength Indication measurement for
* the currently tuned station.
*/
byte getRSSI(void);
/*
* Description:
* Returns the currently configured FM band and channel spacing.
*/
word getBandAndSpacing(void);
#endif /* RDA5807M_H_ */
#include "RDA5807M.h"
void I2C_Init(void)
{
TWBR=0x20; //скорость передачи (при 8 мГц получается 100 кГц) надо настроить ?
}
void I2C_Start(void)
{
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
while(!(TWCR&(1<<TWINT)));//подождем пока установится TWIN
}
void I2C_Stop(void)
{
TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN);
}
int I2C_WriteByte(unsigned char c)
{
TWDR=c;//запишем байт в регистр данных
TWCR = (1<<TWINT)|(1<<TWEN);//включим передачу данных
while(!(TWCR&(1<<TWINT)));//подождем пока установится TWIN
//if ((TWSR & 0xF8) != I2C_MT_DATA_ASK) return 1; else
return 0;
}
unsigned char I2C_ReadByte(void)
{
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);//включим прием данных
while(!(TWCR & (1<<TWINT)));//подождем пока установится TWIN
//if ((TWSR & 0xF8) != I2C_MR_DATA_ASK) return 1; else
return TWDR;
}
unsigned char I2C_ReadLastByte(void)
{
TWCR = (1<<TWINT)|(1<<TWEN);//включим прием данных
while(!(TWCR&(1<<TWINT)));//подождем пока установится TWIN
//if ((TWSR & 0xF8) != I2C_MR_DATA_NASK) return 1; else
return TWDR;
}
void begin(byte band) {
I2C_Init (); //Wire.begin();
setRegister(RDA5807M_REG_CONFIG, RDA5807M_FLG_DHIZ | RDA5807M_FLG_DMUTE |
RDA5807M_FLG_BASS | RDA5807M_FLG_SEEKUP | RDA5807M_FLG_RDS |
RDA5807M_FLG_NEW | RDA5807M_FLG_ENABLE);
updateRegister(RDA5807M_REG_TUNING, RDA5807M_BAND_MASK, band);
}
void end(void) {
setRegister(RDA5807M_REG_CONFIG, 0x00);
}
void setRegister(byte reg, const word value) {
I2C_Start();
I2C_WriteByte(RDA5807M_I2C_ADDR_RANDOM); //Wire.beginTransmission(RDA5807M_I2C_ADDR_RANDOM);
I2C_WriteByte(reg); //Wire.write(reg);
I2C_WriteByte(value >> 8); //Wire.write(highByte(value));
I2C_WriteByte(value & 0xFF); //Wire.write(lowByte(value));
I2C_Stop(); //Wire.endTransmission(true);
}
word getRegister(byte reg) {
word result;
I2C_Start();
I2C_WriteByte(RDA5807M_I2C_ADDR_RANDOM); //Wire.beginTransmission(RDA5807M_I2C_ADDR_RANDOM);
I2C_WriteByte(reg); ///Wire.write(reg);
//Wire.endTransmission(false);
//Wire.requestFrom(RDA5807M_I2C_ADDR_RANDOM, 2, true);
//Don't let gcc play games on us, enforce order of execution.
result = (word)I2C_ReadByte() << 8;//result = (word)Wire.read() << 8;
result |= I2C_ReadLastByte();//result |= Wire.read();
I2C_Stop();
return result;
}
void setRegisterBulk(byte count, const word regs[]) {
I2C_Start();
I2C_WriteByte(RDA5807M_I2C_ADDR_SEQRDA); //Wire.beginTransmission(RDA5807M_I2C_ADDR_SEQRDA);
for(byte i=0; i < count; i++) {
I2C_WriteByte(regs[i] >> 8); //Wire.write(highByte(regs[i]));
I2C_WriteByte(regs[i] & 0xFF);//Wire.write(lowByte(regs[i]));
}
I2C_Stop();
}
void getRegisterBulk(byte count, word regs[]) {
I2C_Start();
I2C_WriteByte(RDA5807M_I2C_ADDR_SEQRDA); //Wire.requestFrom(RDA5807M_I2C_ADDR_SEQRDA, count * 2, true);
for(byte i=0; i < count; i++) {
//Don't let gcc play games on us, enforce order of execution.
regs[count] = (word)I2C_ReadByte() << 8;//regs[count] = (word)Wire.read() << 8;
regs[count] |= I2C_ReadByte();//regs[count] |= Wire.read();
}
I2C_Stop();
}
void setRegisterBulk_memory(const TRDA5807MRegisterFileWrite *regs) {
const uint8_t * const ptr = (uint8_t *)regs;
I2C_Start();
I2C_WriteByte(RDA5807M_I2C_ADDR_SEQRDA); //Wire.beginTransmission(RDA5807M_I2C_ADDR_SEQRDA);
for(byte i=0; i < sizeof(TRDA5807MRegisterFileWrite); i++)
I2C_WriteByte(ptr[i]);//Wire.write(ptr[i]);
I2C_Stop(); //Wire.endTransmission(true);
}
void getRegisterBulk_memory(TRDA5807MRegisterFileRead *regs) {
uint8_t * const ptr = (uint8_t *)regs;
I2C_Start();
I2C_WriteByte(RDA5807M_I2C_ADDR_SEQRDA); //Wire.requestFrom(RDA5807M_I2C_ADDR_SEQRDA, sizeof(TRDA5807MRegisterFileRead), true);
for(byte i=0; i < sizeof(TRDA5807MRegisterFileRead); i++)
ptr[i] = I2C_ReadByte(); //ptr[i] = Wire.read();
I2C_Stop();
}
char volumeUp(void) {
const byte volume = getRegister(RDA5807M_REG_VOLUME) & RDA5807M_VOLUME_MASK;
if (volume == RDA5807M_VOLUME_MASK)
return 0;
else {
updateRegister(RDA5807M_REG_VOLUME, RDA5807M_VOLUME_MASK, volume + 1);
return 1;
}
}
char volumeDown(char alsoMute) {
const byte volume = getRegister(RDA5807M_REG_VOLUME) & RDA5807M_VOLUME_MASK;
if (volume) {
updateRegister(RDA5807M_REG_VOLUME, RDA5807M_VOLUME_MASK, volume - 1);
if(!(volume - 1) && alsoMute == 1)
//If we are to trust the datasheet, this is superfluous as a volume
//of zero triggers mute & HiZ on its own.
mute();
return 1;
} else
return 0;
}
void seekUp(char wrap) {
updateRegister(RDA5807M_REG_CONFIG,
(RDA5807M_FLG_SEEKUP | RDA5807M_FLG_SEEK |
RDA5807M_FLG_SKMODE),
(RDA5807M_FLG_SEEKUP | RDA5807M_FLG_SEEK |
(wrap ? 0x00 : RDA5807M_FLG_SKMODE)));
}
void seekDown(char wrap) {
updateRegister(RDA5807M_REG_CONFIG,
(RDA5807M_FLG_SEEKUP | RDA5807M_FLG_SEEK |
RDA5807M_FLG_SKMODE),
(0x00 | RDA5807M_FLG_SEEK |
(wrap ? 0x00 : RDA5807M_FLG_SKMODE)));
}
void mute(void) {
updateRegister(RDA5807M_REG_CONFIG, RDA5807M_FLG_DMUTE, 0x00);
}
void unMute(char minVolume) {
if (minVolume == 1)
updateRegister(RDA5807M_REG_VOLUME, RDA5807M_VOLUME_MASK, 0x1);
updateRegister(RDA5807M_REG_CONFIG, RDA5807M_FLG_DMUTE, RDA5807M_FLG_DMUTE);
}
const word RDA5807M_BandLowerLimits[5] = { 8700, 7600, 7600, 6500, 5000 };
const word RDA5807M_BandHigherLimits[5] = { 10800, 9100, 10800, 7600, 6500 };
const byte RDA5807M_ChannelSpacings[4] = { 100, 200, 50, 25 };
word getBandAndSpacing(void) {
byte band = getRegister(RDA5807M_REG_TUNING) & (RDA5807M_BAND_MASK |
RDA5807M_SPACE_MASK);
//Separate channel spacing
const byte space = band & RDA5807M_SPACE_MASK;
if ( ((band & RDA5807M_BAND_MASK) == RDA5807M_BAND_EAST) && !(getRegister(RDA5807M_REG_BLEND) & RDA5807M_FLG_EASTBAND65M))
//Lower band limit is 50MHz
band = (band >> RDA5807M_BAND_SHIFT) + 1;
else
band >>= RDA5807M_BAND_SHIFT;
return ((space<<8)|band);
}
word getFrequency(void) {
const word spaceandband = getBandAndSpacing();
return RDA5807M_BandLowerLimits[spaceandband & 0xFF] + (getRegister(RDA5807M_REG_STATUS) & RDA5807M_READCHAN_MASK) * (RDA5807M_ChannelSpacings[spaceandband >> 8] / 10);
}
char setFrequency(word frequency) {
const word spaceandband = getBandAndSpacing();
const word origin = RDA5807M_BandLowerLimits[spaceandband & 0xFF];
//Check that specified frequency falls within our current band limits
if (frequency < origin ||
frequency > RDA5807M_BandHigherLimits[spaceandband & 0xFF])
return 0;
//Adjust start offset
frequency -= origin;
const byte spacing = RDA5807M_ChannelSpacings[spaceandband >> 8];
//Check that the given frequency can be tuned given current channel spacing
if (frequency * 10 % spacing)
return 0;
//Attempt to tune to the requested frequency
updateRegister(RDA5807M_REG_TUNING, RDA5807M_CHAN_MASK | RDA5807M_FLG_TUNE,
((frequency * 10 / spacing) << RDA5807M_CHAN_SHIFT) |
RDA5807M_FLG_TUNE);
return 1;
}
byte getRSSI(void) {
return (getRegister(RDA5807M_REG_RSSI) & RDA5807M_RSSI_MASK) >> RDA5807M_RSSI_SHIFT;
}
void updateRegister(byte reg, word mask, word value)
{
setRegister(reg, (getRegister(reg) & ~mask) | value);
};
#ifndef MAIN_H_
#define MAIN_H_
#include <avr/io.h>
#include "RDA5807M.h"
#endif /* MAIN_H_ */
#include "main.h"
word frequency,status;
byte RSS;
int main(void)
{
begin(RDA5807M_BAND_WEST);
/* Replace with your application code */
while (1)
{
char command = 'm';//Serial.read();
switch(command){
case 'v': volumeDown(0); break;
case 'V': volumeUp(); break;
case 's': seekDown(1); break;
case 'S': seekUp(1); break;
case 'm': mute(); break;
case 'M': unMute(0); break;
case 'f': frequency = getFrequency(); break;
case 'q': RSS = getRSSI(); break;
case 't': status = getRegister(RDA5807M_REG_STATUS); break;
case '?': break;
}
}
}
Вт окт 30, 2018 13:35:26
Вт окт 30, 2018 13:41:17
Вт окт 30, 2018 13:42:48
Вт окт 30, 2018 13:57:39
Вт окт 30, 2018 14:08:31
Вт окт 30, 2018 14:24:16
В этой теме я написал что для VisualStudio есть расширение для разработки под другие МК, а не только AVR. Возможно ТС об этом не знал, ведь он написал что выбрал AVR только из-за поддержки VisualStudio. В чем я не прав?Аlex писал(а):Что не тема - так в ней Вы со своими "дешёвыми" и "крутыми" чипами. Может уже хватит ?
Вт окт 30, 2018 17:27:09
Ср окт 31, 2018 13:37:20
Ср окт 31, 2018 13:54:09
Ср окт 31, 2018 15:04:40
Пт ноя 02, 2018 09:54:50
Вс ноя 04, 2018 10:11:56
Вс ноя 04, 2018 11:36:19
Вс ноя 04, 2018 12:05:19