Тема: Простое радио Atmega8
Радио на модуле rda5807 + энкодер + дисплей на 74нс595(статическая индикация). Было желание сделать без помех от индикатора, особенно когда монтаж конечного изделия плотный.
/*
*
* Find RDA5807M code at: https://github.com/lucsmall/Arduino-RDA5807M
*
* "Talking about my Arduino sketch for the RDA5807M FM Radio IC"
* http://youtu.be/9TegkAu96nE
*
* "Connecting the RDA5807M FM Radio IC to an Arduino"
* https://youtu.be/2j1hX4uzkQ8
*
* "Making my Arduino controlled RDA5807M FM Radio"
* https://youtu.be/4pZmkeqg5h8
*/
#include <Wire.h>
#include <EEPROM.h>
int dataPin = 8; //Пин подключен к DS входу 74HC595
int latchPin = 9; //Пин подключен к ST_CP входу 74HC595
int clockPin = 10; //Пин подключен к SH_CP входу 74HC595
int frequency,n1,n2,n3,n4;
int a,b,c,d;
uint32_t tmr1;
byte flag1=0;
/* Rotary Encoder: */
/*
const int clkPin = 5; // clk - pin 5
const int dtPin = 6; // dt - pin 6
const int swPin = 2 ; // sw - pin 2
*/
int clkPin = 5; // clk - pin 5
int dtPin = 6 ; // dt - pin 6
int swPin = 7 ; // sw - pin 2
/* Select the frequency we want to tune to by way
* of selecting the channel for the desired frequency
*/
uint16_t channel = EEPROM.read(0);
/*
* assuming band starts at 87.0MHz (per settings below)
* and channel spacing of 100kHz (0.1MHz) (per settings below)
* then channel can be derived as follows:
*
* channel = (<desired freq in MHz> - 87.0) / 0.1
*
* which is the same as:
* <10 x desired freq in MHz> - 870
*
* some examples:
* channel 145 dec = 101.5 MHz
* channel 153 dec = 102.3 MHz
* channel 177 dec = 104.7 MHz
* channel 193 dec = 106.3 MHz
* channel 209 dec = 107.9 MHz
* 191 = 106.1 Vikerraadio
* 187 = 105.7 Klassika raadio
*/
/* address of the RDA5807 on two wire bus */
#define RDA5807M_ADDRESS 0b0010000 // 0x10
#define BOOT_CONFIG_LEN 12
#define TUNE_CONFIG_LEN 4
/*
* These bytes set our initial configuration
* We don't bother to tune to a channel at this stage.
* But instead initiate a reset.
*/
uint8_t boot_config[] = {
/* register 0x02 */
0b11100000,
/*
* DHIZ audio output high-z disable
* 1 = normal operation
*
* DMUTE mute disable
* 1 = normal operation
*
* MONO mono select
* 0 = stereo
*
* BASS bass boost
* 0 = disabled
*
* RCLK NON-CALIBRATE MODE
* 0 = RCLK is always supplied
*
* RCLK DIRECT INPUT MODE
* 0 = ??? not certain what this does
*
* SEEKUP
* 0 = seek in down direction
*
* SEEK
* 0 = disable / stop seek (i.e. don't seek)
*/
0b00000111,
/*
* SKMODE seek mode:
* 0 = wrap at upper or lower band limit and contiue seeking
*
* CLK_MODE clock mode
* 000 = 32.768kHZ clock rate (match the watch cystal on the module)
*
* RDS_EN radio data system enable
* 0 = disable radio data system
*
* NEW_METHOD use new demodulate method for improved sensitivity
* 0 = presumably disabled
*
* SOFT_RESET
* 1 = perform a reset
*
* ENABLE power up enable:
* 1 = enabled
*/
/* register 0x03 */
/* Don't bother to tune to a channel at this stage*/
0b00000000,
/*
* CHAN channel select 8 most significant bits of 10 in total
* 0000 0000 = don't boher to program a channel at this time
*/
0b00000000,
/*
* CHAN two least significant bits of 10 in total
* 00 = don't bother to program a channel at this time
*
* DIRECT MODE used only when test
* 0 = presumably disabled
*
* TUNE commence tune operation
* 0 = disable (i.e. don't tune to selected channel)
*
* BAND band select
* 00 = select the 87-108MHz band
*
* SPACE channel spacing
* 00 = select spacing of 100kHz between channels
*/
/* register 0x04 */
0b00001010,
/*
* RESERVED 15
* 0
*
* PRESUMABLY RESERVED 14
* 0
*
* RESERVED 13:12
* 00
*
* DE de-emphasis:
* 1 = 50us de-emphasis as used in Australia
*
* RESERVED
* 0
*
* SOFTMUTE_EN
* 1 = soft mute enabled
*
* AFCD AFC disable
* 0 = AFC enabled
*/
0b00000000,
/*
* Bits 7-0 are not specified, so assume all 0's
* 0000 0000
*/
/* register 0x05 */
0b10001000,
/*
* INT_MODE
* 1 = interrupt last until read reg 0x0C
*
* RESERVED 14:12
* 000
*
* SEEKTH seek signal to noise ratio threshold
* 1000 = suggested default
*/
0b00001111,
/*
* PRESUMABLY RESERVED 7:6
* 00
*
* RESERVED 5:4
* 00
*
* VOLUME
* 1111 = loudest volume
*/
/* register 0x06 */
0b00000000,
/*
* RESERVED 15
* 0
*
* OPEN_MODE open reserved registers mode
* 00 = suggested default
*
* Bits 12:8 are not specified, so assume all 0's
* 00000
*/
0b00000000,
/*
* Bits 7:0 are not specified, so assume all 0's
* 00000000
*/
/* register 0x07 */
0b01000010,
/*
* RESERVED 15
* 0
*
* TH_SOFRBLEND threshhold for noise soft blend setting
* 10000 = using default value
*
* 65M_50M MODE
* 1 = only applies to BAND setting of 0b11, so could probably use 0 here too
*
* RESERVED 8
* 0
*/
0b00000010,
/*
* SEEK_TH_OLD seek threshold for old seek mode
* 000000
*
* SOFTBLEND_EN soft blend enable
* 1 = using default value
*
* FREQ_MODE
* 0 = using defualt value
*/
};
/* After reset, we can tune the device
* We only need program the first 4 bytes in order to do this
*/
uint8_t tune_config[] = {
/* register 0x02 */
0b11100000,
/*
* DHIZ audio output high-z disable
* 1 = normal operation
*
* DMUTE mute disable
* 1 = normal operation
*
* MONO mono select
* 0 = stereo
*
* BASS bass boost
* 0 = disabled
*
* RCLK NON-CALIBRATE MODE
* 0 = RCLK is always supplied
*
* RCLK DIRECT INPUT MODE
* 0 = ??? not certain what this does
*
* SEEKUP
* 0 = seek in down direction
*
* SEEK
* 0 = disable / stop seek (i.e. don't seek)
*/
0b00000101,
/*
* SKMODE seek mode:
* 0 = wrap at upper or lower band limit and contiue seeking
*
* CLK_MODE clock mode
* 000 = 32.768kHZ clock rate (match the watch cystal on the module)
*
* RDS_EN radio data system enable
* 0 = disable radio data system
*
* NEW_METHOD use new demodulate method for improved sensitivity
* 0 = presumably disabled
*
* SOFT_RESET
* 0 = don't reset this time around
*
* ENABLE power up enable:
* 1 = enabled
*/
/* register 0x03 */
/* Here's where we set the frequency we want to tune to */
(channel >> 2),
/* CHAN channel select 8 most significant bits of 10 in total */
((channel & 0b11) << 6 ) | 0b00010000
/*
* CHAN two least significant bits of 10 in total
*
* DIRECT MODE used only when test
* 0 = presumably disabled
*
* TUNE commence tune operation
* 1 = enable (i.e. tune to selected channel)
*
* BAND band select
* 00 = select the 87-108MHz band
*
* SPACE channel spacing
* 00 = select spacing of 100kHz between channels
*/
};
void setup()
{
// Serial.begin(9600);
/* Conect to RDA5807M FM Tuner: */
Wire.begin(); /* join i2c bus (address optional for master) */
Wire.beginTransmission(RDA5807M_ADDRESS); /* Sending boot configuration (device should reset) */
Wire.write(boot_config, BOOT_CONFIG_LEN); /* Write the boot configuration bytes to the RDA5807M */
Wire.endTransmission();
Wire.beginTransmission(RDA5807M_ADDRESS); /* Tuning to channel */
Wire.write(tune_config, TUNE_CONFIG_LEN); /* Write the tuning configuration bytes to the RDA5807M */
Wire.endTransmission();
pinMode(clkPin, INPUT);
pinMode(dtPin, INPUT);
pinMode(swPin, INPUT);
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
digitalWrite(latchPin, LOW);
for(int i=0;i<5;i++){
shiftOut(dataPin, clockPin, MSBFIRST, 0b10111111);}
digitalWrite(latchPin, HIGH);
}//setup end
void loop()
{
if (flag1==0&&millis() - tmr1>500)
{
tmr1 = millis();
myChangeChannel(channel);
output();
flag1=1;}
/* Read Rotary Encoder: */
int change = getEncoderTurn();
if (change > 0){
channel++;
myChangeChannel(channel);
}
else if(change < 0){
channel--;
myChangeChannel(channel);
}
if(channel > 210)
{
channel = 210;
}
if(channel < 1)
{
channel = 1;
}
frequency = channel+870;
n1 = (frequency / 1000) % 10;
n2 = (frequency / 100) % 10;
n3 = (frequency / 10) % 10;
n4 = frequency % 10;
switch (n1)
{
case 0:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
a = 255;
break;
case 1:
a = 249;
break;
}
switch (n2)
{
case 0:
b = 0b11000000;
break;
case 1:
b = 249;
break;
case 2:
b =164;
break;
case 3:
b=176;
break;
case 4:
b=153;
break;
case 5:
b = 146;
break;
case 6:
b =130;
break;
case 7:
b = 248;
break;
case 8:
b = 128;
break;
case 9:
b =144;
break;
}
switch (n3)
{
case 0:
c = 0b01000000;
break;
case 1:
c = 121;
break;
case 2:
c = 36;
break;
case 3:
c= 0b00110000;
break;
case 4:
c=25;
break;
case 5:
c = 18;
break;
case 6:
c =02;
break;
case 7:
c = 120;
break;
case 8:
c = 0;
break;
case 9:
c =16;
break;
}
switch (n4)
{
case 0:
d = 0b11000000;
break;
case 1:
d = 249;
break;
case 2:
d = 164;
break;
case 3:
d = 0b10110000;
break;
case 4:
d=153;
break;
case 5:
d = 146;
break;
case 6:
d =130;
break;
case 7:
d = 248;
break;
case 8:
d = 128;
break;
case 9:
d = 144;
break;
}
if(change!=0){
output();
}//delay(100);
if(digitalRead(swPin)==LOW){
EEPROM.update(0,channel);}
while(digitalRead(swPin)==LOW){
digitalWrite(latchPin, LOW);
for(int i=0;i<5;i++){
shiftOut(dataPin, clockPin, MSBFIRST, 255);}
digitalWrite(latchPin, HIGH);
delay(100);
output();
delay(100);
}
}//loop end
/*
* Function to read Rotary Encoder turn:
* left or right
* Returns: 1 or -1
*/
int getEncoderTurn(void)
{
static int oldA = HIGH; // set the oldA as HIGH
static int oldB = HIGH; // set the oldB as HIGH
int result = 0;
int newA = digitalRead(clkPin); // read the value of clkPin to newA
int newB = digitalRead(dtPin); // read the value of dtPin to newB
if (newA != oldA || newB != oldB) // if the value of clkPin or the dtPin has changed
{
/* something has changed */
if (oldA == HIGH && newA == LOW)
{
result = (oldB * 2 - 1);
/* Serial.print("Result: ");
Serial.println(result); */
}
}
oldA = newA;
oldB = newB;
return result; // 1 or -1
}
/*
* Function to change channel on radio RDA5807
* Example: channel = 191
*/
void myChangeChannel(int channel){ /* void if nothing is returned else int */
/*
* first write new channel to tune_config massive
*/
tune_config[2] = (channel >> 2);
tune_config[3] = ((channel & 0b11) << 6 ) | 0b00010000;
Wire.begin();
Wire.beginTransmission(RDA5807M_ADDRESS);
Wire.write(tune_config, TUNE_CONFIG_LEN);
Wire.endTransmission();
}
void output()
{
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, d);
shiftOut(dataPin, clockPin, MSBFIRST, c);
shiftOut(dataPin, clockPin, MSBFIRST, b);
shiftOut(dataPin, clockPin, MSBFIRST, a);
digitalWrite(latchPin, HIGH);
}
Энкодер
схема дисплея
Примерная печатная плата
Данный контент доступен только зарегистрированным пользователям.
Плата ардуино NG or older. Чип Atmega8. Создаем прошивку: Скетч -Экспорт бинарного файла.В папке скетча будет прошивка.