完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
`````` 本帖最后由 friend0720 于 2016-9-23 10:18 编辑 前言 单片机是一门综合技术,它要求学习者具有一定的电子电路基础,和一定的 C 语言或汇编语言基础。当然如果你学习过《微机原理》那就更好了。C 语言是目前单片机开发最常用到的开发语言,因此请务必学好 C 语言。 同时单片机又是一门实践性很强的技术,如果不亲自动手搭建电路编写程序,是很难真正学会单片机的。下面说说单片机学习的主要过程: 1. 确定一款单片机作为自己的学习目标。目前主流8位单片机有stm8、AVR、PIC等。 2. 搜集该型单片机的各种学习资料。比如书籍、论坛帖子、视频教程等。 3. 下载并搭建软件开发环境 4. 购买硬件开发工具、烧录器、调试器、各种元器件。搭建单片机最小系统,编写程序驱动各种片内资源。 5. 扩展外围电路,并为之编写驱动程序。 后续本人将以ATmega16单片机为例,介绍具体的学习过程。下面是未来我们开发板的大致模样。 送给初学者的一句话:“勿在浮沙筑高台” 遥远的海 (待续) 附件加密!请勿下载! ``````
评分
|
||
相关推荐
715 个讨论
|
||
|
|
|
|
|
|
感谢楼主分享好多东西
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include #include // Power Reduction lib #include // Sleepy lib #include //ISR(WDT_vect) { Sleepy::watchdogEvent(); } // Let Sleepy handle WDT interrupt // LCD (6 wire connection or 2 wire I2C connection) #include #include #include #include #include #include #include #include #include // PinChangeInt lib #define NO_PORTB_PINCHANGES // to indicate that port b will not be used for pin change interrupts #define NO_PORTC_PINCHANGES // to indicate that port c will not be used for pin change interrupts #define NO_PORTJ_PINCHANGES // to indicate that port j will not be used for pin change interrupts #define NO_PORTK_PINCHANGES // to indicate that port k will not be used for pin change interrupts #define NO_PIN_STATE // to indicate that you don't need the pinState #define NO_PIN_NUMBER // to indicate that you don't need the arduinoPin #include // pin definitions / constants / decalarations : ATMega328 // AK4113 spi const byte AK4113_cspin = 6; // AK4399 spi const byte AK4399L_cspin = 7; const byte AK4399R_cspin = 8; // power down const byte AK4399_pdn = 9; const byte AK4113_pdn = 10; // switches const byte SW0_pin = 3; // vol/select up const byte SW1_pin = 4; // vol/select down const byte SW2_pin = 5; // function select (volume, channel, filter) const int SW_debounce = 5; // debounce delay in ms byte SW0_off = 1; byte SW1_off = 1; byte SW2_off = 1; unsigned long SW0_time, SW1_time; const int VOL_repeat = 50; // #ms repeat of volume up/down, the smaller the faster const int VOL_rstart = 200; // #ms first delay repeat // lock interrupt pin const byte LOCK_pin = 2; // AK4399 registers byte AK4399_C2; // 0x01 : control register 2: muting, filter // DAC settings byte Freq = 0; // 0 = no audio byte MCK_mode = 0; // MCK mode, initialized on first lock volatile byte INT0_event = 1; boolean DAC_reset = true; // User definable ------------------------------ #define DAC_CHANNEL_SAVE 512 // (optional)remember selected Channel after power-off, 512 = EEPROM address, writable at least 100.000 times byte Filter = 0; // default Filter = Sharp roll-off = 0 (Short delay = 1) byte Channel = 0; // Channel at startup 0-2 byte Volume = 255; // Volume at startup. set value 0(min)-255(max) // --------------------------------------------- /* sampling frequencies of AK4113. AK4113 can lock on frequencies AK4399 can't handle, 7 freqs remain 0 44.1 2 1 - no output 2 48 3 3 32 1 4 22.05 no output 5 11.03 no output 6 24 no output 7 16 no output 8 88.2 4 9 8 no output A 96 5 B 64 no output C 176.4 6 D - no output E 192 7 F - no output */ const byte AK4113_00H[8] = { // AK4113 register 00H register setting B00000000, B00001011, // 44.1, 48, 32 -------> MCK = 512fs, mode 2 B00001011, B00001011, B00000011, // 88.2, 96 -------> MCK = 256fs, mode 0 B00000011, B00001111, // 176.4, 192 -------> MCK = 128fs, mode 3 B00001111 }; const byte AK4113_03H[3] = { // AK4113 register 03H setting B01000001, // coax B01000000, // toslink B01000010 // u*** }; // LCD display settings // 2 wire LCD I2C-> uses SDA (pin A4) and SCL (pin A5) // LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // 6 wire LCD, uses A0-A5 LiquidCrystal lcd(14, 15, 16, 17, 18, 19); // (RS,EN,D4,D5,D6,D7) = (A0,A1,A2,A3,A4,A5) //const int DP_delay = 10000; // the time display is on/ready //unsigned long DP_timeout = 0; byte DP_func = 0; // Display Function: 0 = volume, 1 = channel, 2 = filter const int func_delay = 5000; // #ms delay before function reset/sleep unsigned long func_timeout = 0; const char* DP_Channels[] = { "coax sp/dif", "toslink ", "USB " }; const char* DP_freqs[] = { " 32", " 44.1", " 48", " 88.2", " 96", "176.4", " 192" }; void setup() { // external mute here // power down AK4113 digitalWrite(AK4113_pdn, LOW); pinMode(AK4113_pdn, OUTPUT); // power down 2xAK4399 digitalWrite(AK4399_pdn, LOW); pinMode(AK4399_pdn, OUTPUT); // setup spi pinMode(AK4113_cspin, OUTPUT); digitalWrite(AK4113_cspin, HIGH); pinMode(AK4399L_cspin, OUTPUT); digitalWrite(AK4399L_cspin, HIGH); pinMode(AK4399R_cspin, OUTPUT); digitalWrite(AK4399R_cspin, HIGH); SPI.begin(); SPI.setBitOrder(MSBFIRST); // the same for all devices SPI.setClockDivider(SPI_CLOCK_DIV8); // 2 MHz speed SPI.setDataMode(SPI_MODE3); // SPI mode for AK4113 and AK4399 : default mode // setup switches / INT input pins pinMode(SW0_pin, INPUT_PULLUP); // defaults to HIGH pinMode(SW1_pin, INPUT_PULLUP); pinMode(SW2_pin, INPUT_PULLUP); pinMode(LOCK_pin, INPUT_PULLUP); // use ATMega pull up (20k) // init LCD lcd.begin(16, 2); // 2 rows, 16 columns // power saving power_adc_disable(); // Disable the ADC to save power, not using it power_timer1_disable(); // only keep timer 0 going (used by millis() ) // ^^more power savings possible for ATMega 2560 /* ------------------------------------------------------------------------------------ AK4399 and AK4113 must have power on their supply pins first to be able to set registers. To be sure some delay is needed. Welcome screen is provided for this. */ DP_welcome(); delay(5000); /* Now continue setup ------------------------------------------------------------------------------------ */ // pin change interrupts PCintPort::attachInterrupt(SW0_pin, &wakeUp, FALLING); PCintPort::attachInterrupt(SW1_pin, &wakeUp, FALLING); PCintPort::attachInterrupt(SW2_pin, &wakeUp, FALLING); PCintPort::attachInterrupt(LOCK_pin, &INT0change, CHANGE); Sleepy::watchdogInterrupts(-1); // Disable WatchDog Timer // get Channel from EEPROM #ifdef DAC_CHANNEL_SAVE Channel = EEPROM.read(DAC_CHANNEL_SAVE); if (Channel > 2) { Channel = 0; } #endif // setup AK4113 : provides master clock init_AK4113(); // setup 2xAK4399 delay(500); // we need MCK of AK4113 to initialize AK4399 init_AK4399(); DP_new(); } void wakeUp() { } // dummy interrupt handler for switches void INT0change() { // interrupt handler for INT0 changes INT0_event = 1; } void loop() { boolean sleep = false; byte a, b, c; byte s0, s1, s2; byte sw0 = 0, sw1 = 0, sw2 = 0; unsigned long time; // Read INT0 status first if (INT0_event) { // transition of INT0 has occurred INT0_event = 0; // clear a = doSPI(AK4113_cspin, B00001000, 0); // read 08H doSPI(AK4113_cspin, B00000111, 0); // read 07H: clear register if (digitalRead(LOCK_pin) == LOW) { if (!DAC_reset) { // external mute here resetDAC(true); } // PLL locked on signal, check validity of fs newFrequency(a); if (Freq) { resetDAC(false); // fs = valid // external unmute here } } else { //PLL lost lock or Sampling Frequency changed Freq = 0; // external mute here resetDAC(true); } if (DP_func == 0) { DP_freq(); // default display } func_timeout = millis() + (unsigned long)func_delay; // delay sleep mode } // read switches, read again after delay, compare with previous state a = digitalRead(SW0_pin); b = digitalRead(SW1_pin); c = digitalRead(SW2_pin); delay(SW_debounce); s0 = (digitalRead(SW0_pin) == a)? 1:0; s1 = (digitalRead(SW1_pin) == b)? 1:0; s2 = (digitalRead(SW2_pin) == c)? 1:0; // SW0: UP repeat when DP_func = 0 if (s0){ // switch state is valid if (a == LOW) { s0 = 0; // button on time = millis(); if (SW0_off) { // button pushed sw0 = 1; SW0_time = time + (unsigned long)VOL_rstart; } else if (DP_func == 0) { // repeat if function = volume if (SW0_time <= time) { // button held down sw0 = 1; SW0_time = time + (unsigned long)VOL_repeat; } } } SW0_off = s0; // remember switch state: 1=off, 0=on } // SW1: DOWN repeat when DP_func = 0 if (s1){ // switch state is valid if (b == LOW) { s1 = 0; time = millis(); if (SW1_off){ // button pushed sw1 = 1; SW1_time = time + (unsigned long)VOL_rstart; } else if (DP_func == 0) { // repeat if function = volume if (SW1_time <= time) { // button held down sw1 = 1; SW1_time = time + (unsigned long)VOL_repeat; } } } SW1_off = s1; // remember switch state: 1=off, 0=on } // SW2 : no repeat if (s2){ // switch state is valid if (c == LOW) { s2 = 0; if (SW2_off) { // switch 2 pressed sw2 = 1; } } SW2_off = s2; } // switches read, do actions if (sw2) { if (++DP_func > 2) { DP_func = 0; // new function = volume SW0_off = SW1_off = 1; // disable hold SW0 and SW1 buttons } DP_new(); func_timeout = millis() + (unsigned long)func_delay; // reset function timeout } else if (sw0 || sw1) { switch(DP_func) { case 0: // volume if (sw0 && SW1_off) { // volume up if (Volume != 255) { Volume++; setVolume(); // set DAC volume //DP_volume(); // display DP_volumedb(); } } else if (sw1 && SW0_off) { // volume down if (Volume) { Volume--; setVolume(); // set DAC volume //DP_volume(); // display DP_volumedb(); } } break; case 1: // channel if (sw0) { // channel up if (++Channel > 2) { Channel = 0; } } else if (sw1) { // channel down if ((Channel--) == 0) { Channel = 2; } } newChannel(); // switch to new Channel DP_channel(); // display break; case 2: // filter Filter = !Filter & 0x01; setFilter(); // switch filter DP_filter(); // display break; } func_timeout = millis() + (unsigned long)func_delay; // reset function timeout } else if (func_timeout <= millis()) { if (DP_func) { // reset display to default DP_func = 0; DP_new(); } SW0_off = SW1_off = SW2_off = 1; sleep = true; } if (sleep && (INT0_event == 0)) { /* lcd.setCursor(0,0); // sleep check lcd.print("S"); */ // Save selected Channel in non-volatile mem #ifdef DAC_CHANNEL_SAVE a = EEPROM.read(DAC_CHANNEL_SAVE); if (a != Channel) { EEPROM.write(DAC_CHANNEL_SAVE, Channel); } #endif // get MCU in sleep mode, wake up on input / interrupt Sleepy::powerDown(); // ATMega will wake up on Switches/INT0 /* lcd.setCursor(0,0); // sleep check lcd.print("c"); */ } } //--------- AK4113 functions void init_AK4113() { digitalWrite(AK4113_pdn, HIGH); // power up // initialize: reset INT registers doSPI(AK4113_cspin, B00000111, 0); // read 07H doSPI(AK4113_cspin, B00001000, 0); // read 08H // Interrupt Mask Control doSPI(AK4113_cspin, B00100100, B11101011); // write 04H, INT0 on UNLCK & STC event only // 05H, Mask Control for INT1: default settings doSPI(AK4113_cspin, B00000111, 0); // read 07H: reset again doSPI(AK4113_cspin, B00001000, 0); // read 08H // I/O Control doSPI(AK4113_cspin, B00100010, B01100000); // write 02H, no ext. osc, no tx output doSPI(AK4113_cspin, B00100011, AK4113_03H[Channel]); // write 03H, default settings, set spdif channel // Reset & Initialize doSPI(AK4113_cspin, B00100000, B00001011); // write 00H, set master clock to 512fs, set clock mode0 // Format & De-emphasis Control doSPI(AK4113_cspin, B00100001, B01011010); // write 01H, audio serial format mode5, default de-emphasis } void newFrequency(byte reg) { byte x,fs; fs = (unsigned byte)reg >> 4; switch (fs) { case 0x00: fs = 2; break; case 0x02: fs = 3; break; case 0x03: fs = 1; break; case 0x08: fs = 4; break; case 0x0A: fs = 5; break; case 0x0C: fs = 6; break; case 0x0E: fs = 7; break; default: fs = 0; } if (fs) { x = AK4113_00H[fs]; // Master Clock setting for fs if (x != MCK_mode) { doSPI(AK4113_cspin, B00100000, x); // set new master clock MCK_mode = x; } } Freq = fs; } void newChannel () { resetDAC(true); doSPI(AK4113_cspin, B00100011, AK4113_03H[Channel]); // switch to new channel } //--------- AK4399 functions void init_AK4399() { byte a; // power up AK4399 is a bit tricky digitalWrite(AK4399_pdn, HIGH); // power up both AK4399 doSPI(AK4399L_cspin, B00100001, B00000011); // 01H: Mute outputs immediately doSPI(AK4399R_cspin, B00100001, B00000011); doSPI(AK4399L_cspin, B00100000, B10000111); // 00H: Interface Mode 3, default settings, RESET = false doSPI(AK4399R_cspin, B00100000, B10000111); doSPI(AK4399L_cspin, B00100010, B00001010); // 02H: MONO Mode, Left Channel, default settings doSPI(AK4399R_cspin, B00100010, B00001000); // 02H: MONO Mode, Right Channel, default settings setVolume(); a = B00000010; // sharp roll-off filter if (Filter) { a = B00100010; // short delay filter } AK4399_C2 = a; doSPI(AK4399L_cspin, B00100001, a); // 01H: No muting, no de-emphasis, no zero-detect, filter doSPI(AK4399R_cspin, B00100001, a); // all registers set, reset dac doSPI(AK4399L_cspin, B00100000, B10000110); // 00H: Interface Mode 3, default settings, RESET = true doSPI(AK4399R_cspin, B00100000, B10000110); } void setFilter() { if (Filter) { AK4399_C2 |= B00100000; // Filter = 1 = Short delay } else { AK4399_C2 &= B11011111; // Filter = 0 = Sharp roll-off } doSPI(AK4399L_cspin, B00100001, AK4399_C2); doSPI(AK4399R_cspin, B00100001, AK4399_C2); } /* void muteDAC(boolean mute) { if (mute) { AK4399_C2 |= B00000001; // SMUTE = 1 } else { AK4399_C2 &= B11111110; // SMUTE = 0 } doSPI(AK4399L_cspin, B00100001, AK4399_C2); doSPI(AK4399R_cspin, B00100001, AK4399_C2); if (mute) { // soft mute, delay 70 ms for total silence delay(70); } } */ void setVolume() { doSPI(AK4399L_cspin, B00100011, Volume); // address 03H : Left Channel Volume doSPI(AK4399R_cspin, B00100011, Volume); doSPI(AK4399L_cspin, B00100100, Volume); // address 04H : Right Channel Volume doSPI(AK4399R_cspin, B00100100, Volume); } void resetDAC(boolean reset) { byte d; DAC_reset = reset; if (reset) { d = B10000110; // 0H: RSTN = 0 } else { d = B10000111; } doSPI(AK4399L_cspin, B00100000, d); doSPI(AK4399R_cspin, B00100000, d); } //--------- LCD display functions void DP_new() { lcd.clear(); lcd.setCursor(0,0); switch (DP_func) { case 0: // default display DP_freq(); lcd.setCursor(0,1); lcd.print("volume"); //DP_volume(); DP_volumedb(); break; case 1: // channel display lcd.print("Channel: "); DP_channel(); break; case 2: // filter display lcd.print("Digital Filter"); DP_filter(); break; } } void DP_channel () { lcd.setCursor(9,0); lcd.print(Channel + 1); lcd.setCursor(0,1); lcd.print(DP_Channels[Channel]); } void DP_filter () { lcd.setCursor(0,1); if (Filter) { lcd.print("short delay "); } else { lcd.print("sharp roll-off"); } } void DP_volume () { // Display volume as a number: 0 - 255 char vol[4]; lcd.setCursor(13,1); sprintf(vol, "%3d", Volume); lcd.print(vol); } void DP_volumedb () { // Display volume in dBs: -127.5dB - 0 dB int d; byte db, fr; char vol[10]; db = 255 - Volume; if (db > 1) { fr = (db & 0x01)? 5:0; // halves d = 0 - (int)(db >> 1); // whole dbs sprintf(vol, "%4d.%1d dB", d, fr); } else if (db) { sprintf(vol, " -0.5 dB"); } else { sprintf(vol, " 0 dB"); } lcd.setCursor(7,1); lcd.print(vol); } void DP_freq () { lcd.setCursor(0,0); lcd.print("ch "); lcd.print(Channel+1); lcd.setCursor(7,0); if (Freq) { lcd.print(DP_freqs[Freq-1]); lcd.print(" kHz"); } else { lcd.print(" no audio"); } } void DP_welcome () { lcd.clear(); lcd.setCursor(0,0); lcd.print(" Digital Audio"); lcd.setCursor(0,1); lcd.print(" Compress V2.0"); } //--------- SPI functions byte doSPI (byte cspin, byte a, byte b ) { byte x; digitalWrite(cspin, LOW); SPI.transfer(a); x = SPI.transfer(b); //x = byte returned when read mode on MISO pin digitalWrite(cspin, HIGH); //writing: data is latched after cs=high shortdelay(); return x; } inline void shortdelay () { __asm__("nopntnopntnopntnopntnopntnopntnopntnopnt"); // delay 500ns at 16Mhz (to ensure min 150ns CS pulse width AK4113 and AK4399) } /* this doesn't work all the time void dacSPI (byte a, byte b ) { digitalWrite(AK4399L_cspin, LOW); // select both DACs at once digitalWrite(AK4399R_cspin, LOW); SPI.transfer(a); SPI.transfer(b); digitalWrite(AK4399L_cspin, HIGH); digitalWrite(AK4399R_cspin, HIGH); shortdelay(); } */ 帮忙编译一下 |
|
|
|
|
|
厉害,挺有用的
|
|
|
|
|
|
你正在撰写讨论
如果你是对讨论或其他讨论精选点评或询问,请使用“评论”功能。
《DNESP32S3使用指南-IDF版_V1.6》第三十五章 摄像头实验
219 浏览 0 评论
《DNESP32S3使用指南-IDF版_V1.6》第三十章 DHT11数字温湿度传感器
574 浏览 0 评论
684 浏览 0 评论
【敏矽微ME32G070开发板免费体验】之原厂2812测试例程解析
1074 浏览 0 评论
1073 浏览 2 评论
【youyeetoo X1 windows 开发板体验】少儿AI智能STEAM积木平台
12049 浏览 31 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-27 22:33 , Processed in 0.919098 second(s), Total 74, Slave 67 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号